Main page

A Guide to Mutt

Contents

Basics
Installing and configuring getmail
Simple mutt configuration
IMAP
Sending mail
Mail headers
Documents and other attachments
HTML mail, following URL's and sending mail from a browser
Macros
Simple filtering
Reading mail
Keeping addresses
Replying to mailing lists
Using mutt with an LDAP address book
More details on multiple accounts
A brief guide to colors in mutt
Spell checking
Mutt and GPG
Stupid mutt tricks
Odds and ends
Newer (and some older) odds and ends

Mutt is not that difficult to get up and running, however, sometimes finding the proper information can be a bit difficult. It is hoped that this will get you started, and show you some nice enhancements that help to make mutt the favorite of many Unix gurus.

This article was recently (February, 2023), mentioned on hacker news. There were several negative comments and I'm sure some are justified. To quickly answer some of the ones that struck me:

In the hacker news comments, people pointed out that it wasn't a "Quick" guide.
It has gradually grown and is no longer a quick guide. I've removed "Quick" from the title.

The age of some of the stuff here.
This was mostly written around 2008 or so, and as mutt is, in my opinion, well made, much of what was written then still holds true. These days, I have far less time and energy, and a quick reread of it shows that much of what held true with, say, Fedora 10, or FreeBSD-6, is still valid for mutt.

Its focus is on POP3.
I prefer to keep my mail on my machine. I do mention IMAP, and do use mutt with my work's IMAP server. In that case, I'm able to filter it on the server side. I don't cover IMAP filtering because I haven't used it and in many cases, you are able to do the filtering on the server. I even use POP3 on my gmail account, although Google does store my sent messages, and I haven't found a way to change that. At any rate, I don't use my gmail account that much.

It doesn't talk about using mutt with oauth.
This is because I haven't had to use oauth, so I don't know anything about it. This does cover using getmail and msmtp with gmail's making 3rd party programs harder to use in the getmail section. As for oauth, if I ever have to use it, I imagine I'll add a section on using it.

Slightly related, I also don't use protonmail. So, there is no information about that, either. Here is an article from Brian Thompson on setting it up but I haven't tried it. There are several guides besides that one to be found with a quick web search.

A quick but important note on paths:
FreeBSD puts 3rd party software in /usr/local. I may remind the reader of this from time to time, but your distribution might do things differently.

Most Linux distros will put mutt, maildrop, msmtp and getmail in /usr/bin, and systemwide configuration files in /etc. NetBSD uses /usr/pkg. OpenBSD puts mutt in /usr/local but puts its systemwide configuration files in /etc. I may write /usr/local/ but on your system, the path may be different.

No doubt there are errors on this page. If you find something, feel free to drop me a line at scottro11[at]gmail.com.

Mutt is a very lightweight email client, and most people use other programs to send, fetch and sort mail. There are many choices, and although later versions of mutt have their own simple pop and smtp utilities this article will cover using mutt in conjunction with getmail to errm, get the mail, msmtp to send it and maildrop to filter it. They give far more flexibility.

Basics

I'm going to assume you already have mutt installed. I think that almost every distribution has a package for it. If not, you can get the tarball from mutt's site. That link goes to the development directory. There have been some changes between mutt-1.4.x and 1.5.x, and this article covers 1.5.x. I would suggest getting the latest development version, 1.5.17, at time of writing. It's configured in the usual way. Download the tarball, uncompress and untar it and do configure, make and make install. If you had downloaded mutt-1.5.17.tar.gz
tar zxvf mutt-1.5.17.tar.gz

Various things are written to your screen
cd mutt-1.5.17
./configure && make && make install

We're going to assume that your main email account is john@example.com. Your password on that account is 1234. Your POP server is pop.example.com and your smtp server is smtp.example.com. Your account on the box is john. The first step is to set up getmail. (Note that while this next section seems a bit involved, it's actually quite easy.)
(If you want to use fetchmail, I have a quick and dirty guide to it which can be viewed here. However, that page hasn't been updated in years. If the reader feels they'd rather use fetchmail, then they'd be better off finding a different tutorial.

Sometimes, I've found that mutt will be slow to open. Some web searching indicates that this may be because it's trying to find the host name. I've found that I can solve this problem by adding my workstation's hostname to /etc/hosts. Most default /etc/hosts files have a line like
127.0.0.1		localhost localhost.my.domain

I just add my workstation's name under that, e.g.
127.0.0.1		myworkstation

It doesn't seem to make a difference if I leave in the default localhost or not.

(Back to Contents)

Installing and configuring getmail

Getmail is available as a package for most distributions. However, the RedHat based distributions, such as CentOS, might have to rely on third party repos. (There is a version that was accepted in early December of 2007. The RPM can be found on RedHat's bugzilla.

This guide is for getmail 4.x, which has some major differences from 3.x. For version 3.x see my getmail 3 page. (I don't know if any distros are still using 3.x, and the program's author strongly recommends upgrading.)

If your distribution doesn't have a package, you will still be able to install it as long as you have python on your system.

Download it from getmail's site. There is a script included in the tarball
tar xzf getmail-4.2.2.tar.gz
cd getmail-4.2.2
python setup.py build
python setup.py install

As of 2020, Gentoo and possibly some other distributions may drop getmail as it is not supporting python3. However, as of July 2020, there is a github version of getmail that should work with python3. I haven't tried it yet. That version's github page can be found here.

Getmail's developer does expect to have a python3 version at some point. However, in the interim, he does mention that one can install python2 and still run getmail as is. (Most Linux distributions and BSD versions have a packaged version).

FreeBSD, as of June, 2021, no longer has a getmail package. To use getmail you have to install py38-getmail6 and the port version is getmail6. It works identically to getmail, but uses python3.

You should have an example getmailrc. It will probably be someplace like /usr/share/examples/getmail or /usr/share/getmail. In FreeBSD, it's in /usr/local/share/examples/getmail. If you use the tarball, it's probably in /usr/share/doc/getmail or /usr/local/share/doc/getmail.

I cover the configuration in more depth on my getmail page. However, in brief, we'll create a .getmail directory and put our getmailrc in there. We'll give our $HOME/.getmail directory full permissions to the owner and nothing to anyone else. So, if you were using FreeBSD, as user john, and in your /home/john directory

mkdir -m 700 .getmail
cp /usr/local/share/examples/getmail/getmailrc-examples .getmail/getmailrc

Next we have to edit the getmailrc.

One can go through the examples and delete the lines they don't want. In the end, we want it to be like this

[options]
verbose = 0
delete = True

[retriever]
type = SimplePOP3Retriever
server = pop.example.com
username = john
password = 1234

[destination]
type = Mboxrd
path = ~/Mail/IN-personal
unixfrom = True

(The unixfrom line is necessary for both procmail and maildrop, which we'll be using later. I don't know about other MDA's.).

The above will work for mbox format. If you have maildir format, then you would change the type from Mboxrd to Maildir and the path to ~/Maildir/IN-personal. You might have to do ~/Maildir/IN-personal/ with the trailing slash, I haven't worked with maildir format for awhile.

Note that the path has to exist--getmail won't create it for you. As mentioned in the next section, mutt will, depending upon the system's defaults, offer to create your Mail or Maildir directory. You can then create a mailbox (or subdirectory in Maildir format) called IN-personal. (You can call it whatever you wish of course, IN-personal is an example.)

If you start filtering email you will change the destination parameter from a mailbox or mail directory to an external program. Using maildrop on a Linux box, where maildrop's path is /usr/bin/maildrop, I have
[destination]
type = MDA_external
path = /usr/bin/maildrop
unixfrom = True

Folks are often making use of gmail's `pop download feature, enabling you to receive your gmail email on your normal client (in this case, of course, mutt.) As gmail uses SSL the above configuration would work save for the SimplePop3Retriever line. For a gmail account, you want, assuming your gmail account is john@gmail.com with a password of 1234

[options]
verbose = 0
delete = True

[retriever]
type = SimplePOP3SSLRetriever
server = pop.gmail.com
username = john@gmail.com
password = 1234

[destination]
type = Mboxrd
path = ~/IN-personal
unixfrom = True
Save that one as a second file in your .getmail directory, e.g., gmailrc. (Each account requires a separate rc file.)

As of May 30th, 2022, Google, whether for good or bad reasons, now considers getmail an insecure app. Therefore, one has to use some special steps to use getmail with gmail.

Firstly, you must turn on 2FA, 2 factor authentication. As I only use gmail on one computer, and a separate gmail account on my phone, which I don't use for any needed email, this was fairly simple. I went to my google account, turned on 2FA, and chose to receive a text sent to my phone. I then generated an app password. I chose custom app, and put in getmail. It generated a 16 character password, which I then added to my $gmailrc, so, instead of password = 1234, it was now password = <16-characterapppass>. Then I could receive mail without problem. I will mention this again when discussing msmtp, but I used the same password for gmail in my msmtp setup. I didn't have to set up a separate app password for it. I also cover this by itself on a separate page

If you're on a box that others use, this means that your email password is visible to the super user. So, you can leave out the password line. However, this will mean that you have to enter it in each time getmail polls your server.

In general, I like to have getmail running in the background, checking for mail every ten minutes. With fetchmail, one does this with the -d option, making it run as daemon. However, getmail doesn't have this option--while some people write a script to do it, I follow the getmail author's advice, and run it as cronjob. For the newcomer unfamiliar with cron, it's used to run a job at regular intervals. There are six fields, minutes, hour, day of month, month, day of week and the actual job itself. In this case, I want getmail to run every ten minutes, regardless of the hour, day, etc. Therefore, the only fields specified are minutes and the actual job. This isn't a page about cron, so I'll simply give the procedure to have getmail poll the pop server every ten minutes.

Again, we'll have a user named john. We'll assume that you're new to this (otherwise, you probably wouldn't be reading this section) and haven't given john a crontab or any specific jobs.
crontab -e

The e means you're going to edit the crontab. You'll probably get an empty editor. In my case, vi is my default editor, so vi opens. For getmail to check for mail every 10 minutes, I would put

*/10 * * * * /usr/local/bin/getmail > /dev/null 2>&1

The numbers refer to minutes, the 4 *'s refer to the fields I'm not specifying, hours, day of month, etc and the last field is the command. The > /dev/null 2>&1 is to prevent it sending you a notificaiton every time it runs.

If you wanted to stop the cronjob for some reason--for example, if you were going to work and get mail there during the day, you just do crontab -e again and comment out the line by putting a # in front of it. Then it would look like
#*/10 * * * * /usr/local/bin/getmail

One quick note of warning. If you wanted the job to run every two hours and made a crontab like this

* */2 * * * 

it would be running every minute. The correct way to specify the job to run every two hours would be

0 */2 * * *
If you have more than one getmailrc file--as in our example above, when you have your example.com account and gmail account, they both have to be specified in your cronjob. -r is used as short for -rcfile, and you don't need a space after the -r.
*/10 * * * * /usr/local/bin/getmail -rgetmailrc -rgmailrc

If you've set up getmail this way, as a cron job, you can either leave mutt open all the time and check your various mailboxes periodically, or, at least in X, use xbuffy to keep track of your emails.

If just watching one mailbox, xbiff, part of xorg-x11-apps, at least in RH based systems, will work. You can set its geometry, color, and so on, either at the command line or by putting entries in your $HOME/.Xdefaults. By default, its size is 48x48 and it watches your default mail, usually /var/spool/mail or something similar. If you make an .Xdefaults entry of
xbiff*file:/home/john/Mail/IN-personal

it will watch that mailbox.

In fluxbox and openbox one can set its position--in fluxbox in your $HOME/.fluxbox/apps and in openbox in $HOME/.config/openbox/rc.xml. That's explained a little more in the link above.

To set geometry and configuration in .Xdefaults, one would use
xbiff*geometry:48x25

to just set the size. To set it to always show up in the bottom right of your window you can use -0-0, with no spaces, in other words
xbiff*geometry:48x25-0-0

To set a corner in .Xdefaults, one uses +0+0 for upper left, -0+0 for upper right, -0-0 for lower right and +0-0 for lower left. To get other locations, you have to play around--for example, on a screen with a resolution of 1920x1080, to get it approximately in the upper middle, I would use 48x25+960+0 and +960-0 to get it on the bottom. To start with +0 puts it at the far left and -0 at the far right. The second number is top or bottom, +0 being the top and -0 being the bottom. (Note that with dwm the top will be below the dwm status bar.) There's a nice page at umd.edu that explains the X Y coordinates in more detail.

(Back to Contents)

Simple mutt configuration

Now to set up mutt. Open up your favorite text editor and make a .muttrc file (note the dot before it). This is where the documentation for Mutt is overly complex for the single user with one account. All that is necessary is:

set folder=~/Mail
folder-hook . "my_hdr From: <john@example.com>"

The ~ refers to the home directory--when you first use mutt it will say something like ~/Mail doesn't exist, create it now? If your system defaults to maildir format (Gentoo did this back when I used it) it will say something like Maildir or maildir instead of Mail. The folder-hook . (a period) means you're setting it for all folders, that is, no matter where you are in mutt when you compose an email.

Usually, there is a system wide muttrc in /etc, /usr/local/etc or someplace similar. Therefore, you can often leave the set folder=~/Mail line out unless you wish to place your default Mail or Maildir somewhere else.

(The system wide file can be in various places. On FreeBSD and Solaris, it's /usr/local/etc/Muttrc. In NetBSD, it's /usr/pkg/etc/Muttrc. OpenBSD has it in /etc/mutt/Muttrc. Mac OSX uses /sw/etc/Muttrc if you install it with fink.

Some, if not most, Linux distributions put it in /etc. In almost all cases and operating systems, it is called Muttrc, with an upper case M.

Many thanks to several members of bsdnexus.com's forums who were kind enough to take the trouble to tell me where their various O/S's put the system wide Muttrc.)

A common problem for those using Maildir format is that when they open mutt they'll get a message like

/home/john/Maildir is not a mailbox

The Maildir format requires 3 subdirectories in there, cur new and tmp. With the maildrop program there's a maildirmake command which will properly create the directory.

maildirmake ~/Maildir

If you've already made your Maildir without the subdirectories you can make them yourself.

cd ~/Maildir
mkdir -m 700 cur new tmp

While on Maildir format, although the mbox format will show the size of each mailbox, letting you know approximately how much new mail you have, Maildir will just show everything as having a size of 512.

However, if you have a mail directory in your Maildir folder, called, for example, IN-personal, you can add the following to your .muttrc

mailboxes ~/Maildir/IN-personal

Then, when you receive new mail an N will appear in front of any mailboxes specified in .muttrc that have new mail.

I haven't looked deeply into this. Sometimes, it doesn't seem to work the way I expected, but these days, as I use mbox format, I never researched it.

When using Maildir format, I've found that you have to create all directories before applying filtering rules. That is, if I have a maildrop or procmail rule to send mail to IN-personal, I have to create the Maildir/IN-personal directory first. This can be done with maildirmake as mentioned above. Again, we'll be dealing with filtering later in this article. Additionally, even a getmailrc that delivers directly to your Maildir directory needs to have the mailboxs created in advance. Again, we'll be dealing with filtering later in this article. Additionally, remember that even a getmailrc that delivers directly to your Maildir directory needs to have the mailboxes created in advance

cd ~/Maildir
maildirmake IN-personal

Otherwise, the directory and subdirectories can once again be created manually.

cd ~/Maildir
mkdir -m 700 IN-personal
cd IN-personal
mkdir -m  700 cur new tmp

If you start getmail, and receive some mail, you'll now be able to read messages in mutt.
The menu is at the top of the display. However, you won't be able to send yet.

One thing to note with a .muttrc--if there are two conflicting rules in it, it will almost always process the last one. However, as noted below, fcc-hooks are an exception. There are other exceptions as well, such as colors.

(Back to Contents)

IMAP

Before beginning, note that some of the options mentioned here, such as header_cache and smtp_user, are not necessarily compiled into mutt by default. For example, on a FreeBSD 9.2-RC3 installation, when I added the set imap_user into my .muttrc, when I next started mutt, I got an error of unknown option. I had to cd into /usr/ports/mail/mutt and reconfigure to add it, by typing make config. I then had to run make deinstall and make install. The easiest way to tell if it's a typo in your .muttrc is to check the systemwide /etc/Muttrc (or /usr/local/etc/Muttrc in FreeBSD's case) to see if the option is there. If it's definitely there, and you're getting an unknown option error when starting mutt, then it indicates that your particular install was compiled without those options. You can always run
mutt -version

which will show you what options are there and not there. For example, a default CentOS install shows me
+USE_SMTP

but a default FreeBSD install, unless I've explicitly configured it in the dialog when installing, will, if I type mutt -version, show -USE_SMTP, indicating that it is not compiled in. Therefore, I had to run make deinstall, make config to get the option dialog, add the support, and then run make reinstall, or make install clean.

Generally, I prefer to pull in my mail, using getmail as described above. However, mutt also works with an IMAP server. If only using one IMAP server with one mailbox, one can add the following to ~/.muttrc. Assuming the user name is john, the password, 1234, and the server name is imap.example.com
set imap_user="john"
set imap_pass="1234"

to send from that server
set smtp_url="smtp://john@imap.server.com"
set smtp_pass="1234"

When sending through most imap servers you need to specifically tell it to keep your sent emails. Assuming your default sent mailbox on the imap server is Sent, you can add this to your $HOME/.muttrc.
set record="Sent"

In my particular, possibly unusual case, although I usually pull in mail from my IMAP server, on occasion, I want to just log into it. Rather than have something set in my .muttrc, I temporarily set the MAIL environment variable. This is generally set to /var/spool/$USERNAME or /var/spool/mail/$USERNAME--in other words, with our user of john, it would be set to /var/spool/mail/john. Resetting it completely might (or might not) affect other things that depend upon the variable, so I just made a little script, checkimap.sh
#!/bin/sh
MAIL=imap://john@imap.example.com
mutt

Make it executable with chmod 700 checkimap.sh. It will then temporarily change your MAIL environment variable to the IMAP server and check your inbox there.

As I don't use this much, I haven't investigated doing much more than that, such as handling multiple imap mailboxes. You might want to add

set folder="imap://john@imap.example.com/"

This should put you in the imap directory, enabling you to see all subfolders. If you just want to be in the inbox, you could use imap://john@imap.example.com/INBOX, assuming that INBOX is the directory you want. If you have all your subdirectories under that, it will work. If your various subdirectories are on the same level as your inbox, then use the first example, that doesn't include "INBOX" (or whatever you call your inbox). By same level, I mean that if using thunderbird, for example, you logged into your imap account, and see INBOX, MYGROUPS, SALES and so on, then all those mailboxes would be on the same level. Other people have one INBOX, and then, inside the INBOX, make their subdirectories. This mutt wiki page goes over using imap with mutt.

In another situation, I found that the above gave me login errors. The address was john@example.com but the server name was mail.example.com. When I used
set imap_user="john@example.com
set folder="imap://john@mail.example.com"

it didn't work. Instead I had to use
set imap_user="john@example.com
set folder="imap://mail.example.com"

Actually, in that case, it was using SSL so I had to change the second line to imaps://mail.example.com. Regardless, the user was my email address, and the folder, rather than user@host, was just the host.

Another thing, that didn't happen to me, but has happened, is that for whatever reason, (perhaps because it was built without SSL or TLS), that mutt won't properly transmit a password from .muttrc. That is, if you have the suggested.
set imap_pass="1234"

you might get a login failed message. However, if you leave out the set_imap_pass from your .muttrc file and just type in the password when requested, it works. I haven't run into this, and only found out about it when researching something else (the problem I mentioned above, when the user is john@example.com and the server is mail.example.com), but mention it as something for a user to try if they're unable to log into their imap account.

Using IMAP can be surprisingly slow. One easy way to speed it up is to create a .mutt_cache in your home directory.
mkdir ~/.mutt_cache

(Note the dot in front of the name, making it a hidden directory). Then, add to your ~/.muttrc
set header_cache="~/.mutt_cache"

Then mutt will cache the IMAP headers in your $HOME/.mutt_cache. This will greatly increase speed with IMAP directories.

Even if not using IMAP, creating a .mutt_cache directory and adding a line referencing it in your .muttrc can speed up mutt's handling of large mbox files or maildir directories.

(Back to Contents)

Sending mail

If you're really impatient, and just want to send mail through a basic pop3 account that doesn't require authorization, you can add the followiong to your .muttrc. Our user John at example.com, doesn't have to provide a username and password to send, only to receive. So, he could add
set smtp_url="smtp://smtp.example.com"

Now, if you hit y to send your mail, it will use your ISP's server.

If your ISP uses a secure server, then it would read something like
set smtp_url="smtps://john:1234@smtp.example.com:465

465 is a commonly used port for smtps. However, always check with your ISP, or read their setup information for sending mail. Gmail uses authentication and TSL, I believe, and for sending, you need to use port 587. The last time I looked, their help site said that you could use either one, but thanks to a post in their forums by K. Frazier, I found that 587 seems to be necessary.

Gmail's smtp_url setting uses smtp, not smtps.

If setting smtp_url to work with gmail, with the username of john@gmail.com and the password of 1234 you would use
set smtp_url="smtp://john@gmail.com@smtp.gmail.com:587"
set smtp_pass="1234"

(Again, you can use an ip address gotten by pinging smtp.gmail.com).

I haven't used that method with gmail in years, and the last time I tried, I got a message no authenticators available. Googling found some solutions for Debian and Ubuntu users (install libsasl2-modules), and in Fedora and CentOS I got it by installing some cyrus-sasl packages. I think the only one I really needed was cyrus-sasl-plain. The others I had were cyrus-sasl, cyrus-sasl-gssapi and cyrus-sasl-lib.

In Arch, it worked without specifically installing anything besides mutt. In my individual case, it was more curiosity, as I have a few different accounts, which leads nicely to my next point.

The smtp_url line is handy if you only have one account, but these days, many people use multiple accounts. Therefore, I recommend msmtp.

The msmtp program has a very simple syntax and the configurations given in the man page are straightforward.

Create a $HOME/.msmtprc file, giving it permissions of 0600 (otherwise, you get an error message.) Again, we'll assume the username of john@example.com with an smtp server of smtp.example.com The file should read
account examplecom
host smtp.example.com
from john@example.com
account default : examplecom

Those are the four absolutely necessary entries. The line account is your own name for the account. You can call it what you wish. The host line is the address of your ISP's smtp server. The from line is the address that appears in the From: part of your email. The account default line is necessary, even if you only have one account, otherwise msmtp exits with an error.

One then adds the following line to .muttrc
set sendmail="/usr/local/bin/msmtp"

(A reminder that I am using /usr/local/bin because that's where it is with FreeBSD. Your system may have it in a different place--one can always check with the command
whereis msmtp

To digress for a moment, don't the set_sendmail line. I once had the somewhat embarrassing situation, after a fresh install, of email constantly failing to send, with occasional success to make it harder to track down. What had happened was that the old install had postfix, and I didn't realize that mail from a particular address was using postfix's settings, as I hadn't set msmtp at all in sendmail, only with some send2-hooks for certain accounts Finally, I realized that this particular account hadn't had a set_sendmail line, or send2-hook line, and was using FreewBSD's dma, which is usually used just for internal emails. Maillog was only showing me that various servers were rejecting the email, with links that indicated my ISP was at fault. So, make sure you do have a default set_sendmail line in your .muttrc or .neomuttrc, or at least a send2-hood with every email account you use. (It was only embarrassing to me, fortunately, I didn't accuse my ISP or mail provider of incompetence, realizing there was a good chance that it was my fault.)

For gmail, it's somewhat different. If the user name is john@gmail.com and he has a gmail password of 1234.


#Gmail 

account gmail
host smtp.gmail.com
from john@gmail.com
auth on
tls on
tls_trust_file /etc/ssl/cert.pem
user john@gmail.com
password 1234
port 587
account default : gmail
Also, as previously mentioned in the getmail section, if using gmail you will need a special app password. If you're using both getmail and msmtp, then you can use the same app password that was generated for getmail. Otherwise, if you're just using smtp for sending, you have to turn on 2FA, and then generate an app password. Where you have a place to put in a custom app, just put msmtp. Note I haven't tested it with only msmtp, I use it with getmail, where one can use getmail's app password with msmtp, but from my experience with getmail, this method should work. Again, if you've already created an app password for getmail, you can use the same one with msmtp.

The man page also gives clear instructions on using msmtp with mutt, including key bindings to quickly switch between say, a gmail account and another account. The following is more or less a recap of the man page.

The msmtp man page advises against the tls_certcheck off. Most distributions have a package that will include it. On Debian (and perhaps Debian based systems) one installs the ca-certificates package and your tls_trust_file would point to /etc/ssl/certs/ca-certificates.crt. On FreeBSD, it's included in the /usr/ports/security/ca_root_nss port and the file is in /usr/local/share/certs/ca-root-nss.crt. FreeBSD installs the ca_root_nss port as a dependency if you install msmtp with openssl or gnutls support. There is also the option to symlink to /etc/ssl/cert.pem.

With ArchLinux, if you install curl, it can be found in /usr/share/curl/curl-ca-bundle.crt. In Fedora and CentOS, I found it in /etc/pki/tls/cert.pem. VoidLinux uses /etc/ssl/cert.pem. Adjust your .msmtprc tls_trust_file line accordingly.

In CentOS, I had to compile msmtp from source. It's relatively trivial, but make sure that you have gnutls and possibly gnutls-devel installed, otherwise, you won't be able to use tls check. For the beginner, unfamiliar with compiling from source, note that with RedHat based distributions, the necessary tools aren't installed by default. So, first make sure you have them.
yum install gcc gcc-c++ make automake kernel-devel

This will pull in several other things, such as kernel-headers, as dependencies. Once this is done, download the tarball from msmtp's site. Get the bz2 file, untar and decompress it, then run configure and make. For example
tar jxvf msmtp-<version>.tar.bz2
cd msmtp-<version>
./configure
make 
make install

After running configure, it will show you the options that it has chosen. Make sure, especially if you're planning to use it with gmail, that it has either tls or SSL. (Again in CentOS and Fedora, you might have to install gnutls and gnutls-devel with yum install gnutls-devel which will pull in gnutls as a dependency.)

As mentioned, msmtp works with multiple accounts. Suppose our user john has the gmail account, john@gmail.com and his account at example.com. He wishes to use both of them, and be able to switch between them at will. The isp account is john@example.com and also has a password of 1234. Unlike gmail, it doesn't require authentication. He wants the normal account to be his default.

He then edits his .msmtprc to read


#Gmail 

account gmail
host smtp.gmail.com
from john@gmail.com
auth on
tls on
tls_trust_file /etc/ssl/cert.pem
user john@gmail.com
password 1234
port 587

account examplecom
host smtp.example.com
from john@example.com

account default : examplecom 

To switch back and forth between accounts, he adds to .muttrc

macro generic "<esc>1" ":set from='John <john@gmail.com>'"
macro generic "<esc>2" ":set from='John <john@example.com>'"

Now, if he wishes to send an email from from gmail, first he hits the escape key and the 1 key. (In this case, this is the numeral one, not a lower case L). If he then hits m to compose mail, it will be sent from the gmail account. If he then wishes to send another email from his isp.com account, he hits the escape key and 2 before hitting m to compose his mail, and the new email will come from john@isp.com

The easiest way to do this is to use the send2-hook. This was lifted almost verbatim from the msmtp section of the the mutt wiki
send2-hook '~f john@gmail.com' 'set sendmail="/usr/local/bin/msmtp -a gmail"'
send2-hook '~f john@example.com' 'set sendmail="/usr/local/bin/msmtp "'
He doesn't need the -a for account for his examplecom account, because it's defined as his default in his .msmtprc.

The man page goes into more detail.

With FreeBSD, to get it working properly with gmail, during installation, I had to specify openssl as an option.
cd /usr/ports/mail/msmtp
make -DWITH_OPENSSL install clean
Note that if you later use portupgrade to upgrade msmtp, you would have to use that with the -m flag, e.g.
portupgrade -m -DWITH_OPENSSL msmtp

There is another even smaller and simpler utility called nbsmtp, which I cover briefly on another page. I'm not sure that it's still around. I also have a page on ssmtp, but ssmtp has been abandoned by its maintainers, so I no longer use it.

(Back to Contents)

Mail headers

Depending upon your computer's systemwide muttrc, mutt might give complete headers for every email. For the average user, unless trying to track a spammer or troubleshoot a mail server's configuration, this can be too much information. Therefore, if one only wants to know the standard info, this hack to the .muttrc file will work. Add the lines
ignore *
unignore date from to cc subject resent-from reply-to x-mailer

(You can change these according to personal taste) The above will just show the from, to, etc rather than the path, etc.

(Back to Contents)

Documents and other attachments

With catdoc or antiword, one can actually view a document in mutt. Install one or the other. They both do similar things. Their main purpose is to take a word document and output it as text.

In .muttrc add the following.
auto_view application/msword

In /etc/mailcap or your home directory .mailcap, add the following. (In the example, we'll use antiword but either catdoc or antiword will work.)
application/msword; antiword %s ; copiousoutput

This should, in most cases, enable you to open the document in line. If you leave the auto_view line out of your .muttrc, the mailcap entry should still enable you to hit v as in view on the attachment, and see it as a text document.

One can do the same with Excel sheets and the xls2csv program. Some systems create default mailcaps, assuming that you're using X, that is, running mutt in an xterminal. They might have
application/msword;  ooffice %s

If that is how you plan to use it, in X, then you probably want to remove the autoview line from your .muttrc. Then, when you receive a .doc attachment, use v to view the attachment, hit enter, and it will open in OpenOffice. I prefer using catdoc as it enables me to view documents without having to run an X session.

If using X and running mutt in terminal, the same method can be used to easily view images and pdfs. Add the following to your $HOME/.mailcap. In this case, we'll assume you use xpdf to view pdf files and feh to view images. You can change these to your preferred applications. For example, Gnome users might want to use eog, Eye of Gnome, for images.
image/*;   feh %s
application/pdf; xpdf %s

Now, if you receive an attached image or pdf and are in X, you can hit v for view and when the file is selected, just hit enter. The feh program will open and display the image.

If you're in console, however, rather than xterm, you can view it later while in X, or hit s for save. It will save the file, by default, to your home directory, and you can then, when in X, view it with your image viewer of choice. One can also, if using framebuffer in terminal, use fbi to view the image, but I haven't done this very much. I think the trick would be to change ~/.mailcap to use fbi for image/* files.

(Back to Contents)

HTML mail, following URL's and sending mail from a browser

In many cases, you can view an html email with the text based w3m browser. Create a file, $HOME/.mailcap. Note the dot in front of the file name. You will often have a system wide /etc/mailcap as well and you can use it as a template.
text/html; /usr/bin/w3m -dump -T text/html %s

will often enable you to view those somewhat annoying html formatted messages. Your $HOME/.muttrc (or .neomuttrc) may need
auto_view text/html
If this doesn't work, I've also had success with
text/html; w3m %s; needsterminal; description=HTML Text; nametemplate=%s.html

Following html in mutt does seem to evolve from time to time, and the reader may just be best off searching the web for a recent article. The best I've seen is actually fairly old, Jason Ryan's page from 2012.

Often, if all else fails, (or even if it doesn't), much of the time, html mail will have a text attachment. If you hit v as in view, when looking at an html mail, you might see a text/html and a text/plain. Mac's Mail.app, among others, seems to do it this way. You can always just arrow down to the text/plain and see if it's readable that way.

To follow url's in an email, I use urlview. I've only done it in FreeBSD and Fedora, but hopefully the reader will be able to modify it for his system. FreeBSD has it in /usr/ports/textproc and I believe Fedora installs it as a dependency of mutt.
Add the following to your .muttrc
macro pager \cb |urlview\n
macro index \cb |urlview\n

Now if I hit ctrl b I simply see a list of urls. I can navigate to the link I wish to follow (with arrow keys or vi commands) and hit enter. The url is shown at the bottom of the screen, hit enter again, and the link opens up.

/usr/bin/xdg-open.

Sometimes, as mentioned in Jason Ryan's blog post (where I got most of the following), some emails have the links hidden in HTML, and it becomes necessary to open a browser to actually view an email. He uses vimprobable, but any browser will do. (I've had trouble building vimprobable or surf, another lightweight browser, on CentOS 6.x for example, so one can use firefox, or dillo which is available on CentOS.) Whether or not you have autoview set, in mailcap, above the w3m lines we've mentioned, one can add
text/html; firefox -new-tab %s; test=test -n "$DISPLAY"

If using dillo, don't use -new-tab.
text/html; dillo %s; test=test -n "$DISPLAY"

The blog post mentions keybindings, but as I find I only have to use this on very rare occasions, if I get such an email, I first hit v for view, and then m which will send it to mailcap. This opens up a browser and shows me the mail. (I should add that one should take care with this, as there can be security issues with automatically displaying images, but in my case, the emails I've had to do this with were from known sources.

Dillo may not display the images. In my own case, I seldom want them anyway, I would just want the necessary links.

Sometimes, hitting v will just show one line, something like no description text/html. Other times, there may be a few lines, such multipart/alternative, text/plain and text/html. In such cases, if you hit m while highlighting multipart or text plain, you may get an error. You have to navigate down, with arrow key or (in vi at least) j to get to the text/html line.

If you use urxvt in X, you can use the urxvt-perls scripts to select a URL address and open it. Many distributions have the urxvt-perls scripts as a package. If not, you can go the github site, and download the url-select script. At time of writing, January 2016, the script can be gotten with
wget
https://raw.githubusercontent.com/muennich/urxvt-perls/master/url-select

Create a directory if it doesn't exist, $HOME/.urxvt/ext and put the script in there. (You may have to create the parent directory, .urxvt, as well. Then add to $HOME/.Xdefaults or $HOME/.Xresources (creating it if it doesn't exist). In the example, for launcher, I use xdg-open. You can change that to your browser of choice, so the urxvt.url-select.launcher can read firefox, chrome, or another browser of your choice.
URxvt.perl-ext: default,url-select
urxvt.keysym.M-u: perl:url-select:select_next
urxvt.url-select.launcher: /usr/bin/xdg-open
urxvt.url-select.underline: true

The Arch Linux wiki has a section on this. One can use matcher instead of url-select, but I haven't tried it. On CentOS-6.x matcher is supplied by rxvt-unicode, but is put in /usr/lib64/urxvt/perl/matcher.

The lines we entered first tell us what perl extension to use. The M-u means the mod, usually the alt key, and u to select a url. The /usr/bin/xdg-open menu is what I use on some Linux distributions--you can also just put /usr/bin/firefox, /usr/bin/chromium or whatever browser you want to use. (You probably don't need the complete path.)

Once this has been done, if you're using urxvt for mutt, if you have urls in the email, and hit alt+u, it should underline them. I use vi, and using vi's navigation keys of j and k for up and down, I can select the previous or next URL. Once it's selected, I can hit enter, and the URL will open in firefox. (which is my default browser. As mentioned, I can change this in .Xdefaults so that it uses a different browser.)

I've only run into this next situation one or two times, but it's worth mentioning. I got a support email saying you missed our message because your email service rejected the HTML. (As Jason Ryan eloquently says, one shouldn't use html email but it's become the de facto standard these days, and it's better to light a candle than curse the darkness.) I could hit -v for view and see the mail, which, in this case, merited an answer. However, reply wasn't available from the view text/html message.

In my .muttrc I have the lines
auto_view text/html
alternative_order text/plain text/html

I changed this, temporarily of course, to
auto_view text/html
alternative_order text/html text/plain

I was then able to read and respond to the html email. (As soon as I did, I changed the order back to my preference of text/plain.)

One last, somewhat related topic. If you wish to use mutt with a graphic browser, it's not difficult. In opera one just goes to Tools => Preferences =>Programs and paths =>E-mail. The default is to use opera's email, but below that you are given the option to open it with another application. I use the following--this will give me a To: as specified in the mailto and also a subject if the subject is coded in the mailto link. I use mlterm as my terminal. You can substitute this with the xterm of your choice.
mlterm -e mutt [-s %s] "%t"

Quote only the %t as shown in the example. That represents the To: line. The %s for the subject has to be in brackets, or it will be passed as one argument--in other words, if the code on the web page was something like mailto:john@example.com?subject=hello, if the %s is not in brackets and you click the link it will come out as something like To:john@example.comhello.

With opera 9.50 beta, on Fedora, it was slightly different. I had to use mutt as the program name. Then, I put the [-s %s] "%t" part in the textbox marked Parameter. Lastly, I checked the box that says Open in terminal.

For Mozilla and firefox, it's a bit more complex. My friend Godwin has a page about it that explains the various steps quite well. I will give a very quick recap here. Go to about:config (if you're not familiar with firefox, just type

about:config

in the address bar. Then, look for the setting

network.protocol-handler.external.mailto

It is probably set to true by default--if not, right click and choose the toggle option. Then, right click any setting, choose New and String. For the string put

network.protocol-handler.app.mailto

For string value put

mailto.sh

Create a script called mailto.sh and put it in /usr/local/bin/ or $HOME/bin or wherever you put your custom scripts, as long as it's in your $PATH. In this example, I am using mlterm, my usual terminal, but use xterm, kterm or whatever you usually prefer

#!/bin/sh
mlterm -e mutt "$1"

Make it executable--if you put it in /usr/local/bin

chmod 755 /usr/local/bin/mailto.sh

For more details, including screenshots, see Godwin's page. (Although he doesn't cover mutt)

One can edit their prefs.js file instead. This is found in $HOME/.mozilla/firefox/something.default directory--the something being a random string of letters and/or numbers. If one chooses this method, the two lines would read

user_pref("network.protocol-handler.app.mailto", "mailto.sh");
user_pref("network.protocol-handler.external.mailto", true);

(The external.mailto line should be unnecessary as it is probably set to true by default.)

A recent upgrade to firefox 3 beta seemed to break this. A bit of googling found the answer at the shallowsky.com site. The solution is to find one more setting in firefox's about:config, network.protocol-handler.warn-external.mailto which will probably be set to false. Set it to true.

Fear not, it only asks you once. After that you can choose to always use this app, or remember my answer or something similar. This fixed the problem for me with firefox 3. (By the way, even the beta seems much improved, at least in Linux, over firefox 2.)

I haven't yet figured out to do this with chromium. I don't think it has a mailto option yet.

(Back to Contents)

Macros

Macros are handy, but the average user finds the mutt handbook's explanation somewhat terse. FreeBSD has some sample macros in /usr/local/share/examples/mutt/sample.muttrc.

The pattern is macro menu key_sequence [description]. That was clear right? Ok, maybe not. This very simple macro will save an email to a mailbox called spam.
macro pager S "s+spam"
macro index S "s+spam"

First, one writes the word macro. This indicates that what follows will be a macro. That was easy, right?

Next, the menu part. This refers to where you are in mutt. The word pager means that you're reading the email, so you could move around in the particular email the same way you would with any pager. The second line of this simple macro also binds the macro to the index--that is, while looking at the list of messages. For example, if I open my FreeBSD-CURRENT mailbox and I have one message highlighted, hitting shift+S (note that these macros are case-sensitive) will affect that message, because I have used the index keyword. So, this macro will work if I am reading a piece of email, or if I'm looking at my list of mail.

Next the capital S. That is the key that I am binding to the macro. You can use the control key, escape key, etc. as well. Had I wanted to use ctl+s (that is, a lower case s) I would use \cs. A backslash and c indicates the ctrl key. A backslash and e (\e) would be the escape key. However, you can also use <esc> to indicate the escape key.

The samples provided with mutt will have things like <save-message>+spam<Enter>. However, I haven't found all that to be necessary. Sometimes the end of line \n seems to be needed and sometimes not. I haven't investigated macros too deeply, but it seems that if, in general, if a one letter command would do something in mutt, it will work in a macro. For instance, in my example, I just have s for save rather than the save-message thing. You'll note, if in mutt that hitting s will bring up a dialog to save a message. So I can use it in my macro. The +spam indicates that it will be saved to my $HOME/Mail/spam mailbox. (By default, mutt looks to save a message in $HOME/Mail/.)

As for key bindings, although the mutt manual refers you to the keybinding section, that seems to have omissions. For example, they do show that both \e and <escape> can represent the escape key, but they don't show the control key, nor does it say you can use <esc> rather than the full word "escape".

It can sometimes be a bit tricky. In general, you attempt to duplicate what you would type while mutt is open. The following is what I would type if I wanted to, while mutt is open, have the sa-learn program examine my spam mailbox and learn that everything in there is spam.
!sa-learn --no-sync --spam --mbox ~/Mail/spam

(A shell command typed while in mutt needs an exclamation point typed before the command). If I want to bind this command to a macro, let's say escape and s I need
macro index \es "!sa-learn --no-sync --mbox --spam ~/Mail/spam<Enter>"

For a nice rundown of using sa-learn, see faisal.com.

(I could also use macro pager but I tend to only use that particular command while looking at the index of messages. There is also macro generic which seems to work anywhere in mutt.)

The command is double-quoted and ends with the word Enter in brackets. In this case, using \n for a newline doesn't work. Also note that I typed an exclamation point within the double quotes. The important thing here is that I am duplicating what I would type while mutt is open. I usually try to get away with \n and if that doesn't work, then try again with Enter in brackets.

Sometimes, a macro might conflict with a default mutt macro or default terminal keybinding. You can see your default keyboard shortcuts in mutt by typing ? while in most menus. For example, I wanted to use ctl+s for something. It didn't work. However using <esc>s worked.

Some googling indicated that this was because ctl+s stops sending data to the terminal. Most Unix and Unix-like terminals still support this. So, if a macro doesn't work, sometimes trying a different keyboard combination might help--at least it should let you know if the problem is your syntax or your chosen combination.

To use the alt key, you can set the following in your .muttrc
set meta_key=yes

If you do this, then using a keyboard macro beginning with \e will work with either the escape or the alt key. It's usually turned off by default. As usual, you can check your system-wide Muttrc. If you leave that set meta_key option at its default of no, then using \e will work with the escape key, but not the alt key.

Another simple macro can be used to invoke getmail for those times when I don't feel like waiting for the cronjob to run.
macro index G "!getmail\n" "Invoke getmail"
macro pager G "!getmail\n" "Invoke getmail"
Now, hitting shift G will run getmail though I've never been able to make this work with any rc file besides the default getmailrc. That is, adding things like -rgmailrc to the macro didn't work.

I'm no expert on macros, but hopefully, this gives you enough of an idea of the syntax so that you can begin using them for yourself

(Back to Contents)

Simple filtering

Mutt depends upon an MDA (Mail Delivery Agent) to deliver the mail. Both sendmail and postfix will do the job on most Linux or BSD installations, however, they could be considered overkill for the single user. Therefore, we're using maildrop. The other reason for using maildrop is to filter your email. For example, on one box, although I have postfix to send mail, when it receives mail, that mail is then sent to maildrop to be filtered.

If you get a reasonable amount of email, eventually you'll want to start filtering it.

(For those who prefer procmail, I have a page on it, that is basically an even quicker start than the procmail quickstart guide here) However, it hasn't been maintained for years.

I use maildrop as my mail delivery agent. Its man pages and even its example pages make it seem more complex than it is for our purposes, yet it is really quite simple.

Note for RedHat based distribution users (Fedora, CentOS, etc. Not applicable to Fedora 10 and later.)
Prior to Fedora 10, RedHat based systems didn't have a package for maildrop. (In Fedora 10, just do yum -y install maildrop.) I've built it from source without problems. The latest maildrop, at time of writing, is 3.0.7-2. To get that to build on CentOS, you need the courier-unicode libraries 1.2 version. The latest rpm I found (though I didn't look that hard) was the nux-desktop repo version (for CentOS-7) which is version 1.1.

On CentOS-7, although there isn't a maildrop rpm that I've found, it is easy to build. I have the nux-desktop repo, which gives me courier-unicode-1.1, a needed dependency, then downloaded the 2.8.1.tar.bz2 maildrop tarball.

For CentOS-8.6, as well as Rocky and AlmaLinux, it is looking for courier-unicode-2.1. I wound up rebuilding a Fedora 32 srpm and installing courier-unicode-2.1, and courier-unicode-dev-2.1 from that, using rpmbuild --rebuild. (Until maildrop is, if ever, added to the repos, the easiest way might be to find the oldest Fedora srpm that can be found and build the courier-unicode, courier-unicode-devel and possibly maildrop, though I used courier's spec file for maildrop and run rpmbuild --rebuild). Then I could build maildrop from the spec file.

NOTE: As of late June, 2022, there are maildrop and courier rpms for RHEL 8 and clones in the EPEL-testing repo. I don't know when it will be moved out of testing, but as of June '22, you no longer have to build your own. I'm leaving the section below in, for general reference if you do want to build it yourself.

You can install rpmdevtools and then run
rpmdev-setuptree

which creates the necessary directories, assuming you want to use the defaults. I downloaded the tarball which is on sourceforge. I untarred it, though I put a copy of the tarball in rpmbuild/SOURCES as the specfile will look for it there. I took the spec included with the tarball, put in in rpmbuild/SPECS and just ran
rpmbuild -bb maildrop.spec

from the rpmbuild/SPECS directory. I first ran sudo yum-builddep maildrop.spec in the same directory which is how I found that one needs courier-unicode and courier-unicode-devel.

I have submitted a request for such a package at Redhat's bugzilla, so readers with an interest can add their comments there.

I want to give my thanks to Tillman Hodgeson for his help with this. All mistakes are, of course, my own, but at any rate, Tillman (whose web page can be found here) showed me how simple it is to use.

First we're going to set up, in the home directory, a .mailfilter file, and only give permissions to the owner. Open your favorite text editor. Let's start with a very simple rule. I belong to a busy mailing list called nylug and I want all mail sent to it to go into its own mailbox in my $HOME/Mail directory.

if (/^To: .*nylug/)
        to Mail/IN-nylug

If using the Maildir format rather than Mail, you may have to add a trailing slash to the mailbox name.

if (/^To: .*nylug/)
        to Maildir/IN-nylug/
Don't put a blank or commented line between the if and to lines. If the to line is not on the line following the if line, it will act as a filter in itself. For example:
if (/^To .*oldaddress/)
#	to Oldmail
	to Newmail

You see I used to send something to Oldmail and now want to send it to Newmail. Instead of deleting the to Oldmail line, I've just commented it out. This won't work properly. Instead, everything that hasn't yet been filtered will be affected by the "to Newmail" line and will go into the Newmail box. If you want to leave the old line for reference then put it underneath the current rule, e.g.,
if (/^To .*oldaddress/)
	to Newmail
#	to Oldmail

Speaking of syntax, my typical entry is something like
if (/^To .*mailinglist/)
    to Mail/IN-mailinglist

which is the mailbox in my ~/Mail directory. If you make an error and type
if (/^To .*mailinglist/)
    to /Mail/IN-mailinglist

You'll see an error that maildrop can't open the mailbox. (It may say error 75 but I haven't made this error enough to be sure on that one.) It can't open the mailbox because it's looking under /Mail, in other words, a directory called Mail that is right under /. Obvious though that one is, it took me awhile to see my typo and realize why I was getting the error.

Another symptom of syntax errors is if you don't get mail that you're expecting, and checking /var/log/maillog shows something like
Unable to create a dot-lock at dev/163761.0.myhost.mydomain.com

It very often means there's a subtle error in $HOME/.mailfilter that may not show up if you run cat testmail |maildrop -V4 -d as discussed elsewhere in this section. A .mailfilter syntax error isn't the only reason for that error but it's a very common one.

Some mailing lists, such as nycbug and freebsd-questions, do things a bit differently. If one replies to a nycbug post, the reply only goes to the original poster unless one cc's the mailing list.

In such a case, poster A sends his message to nycbug. A rule like the one above will catch it (obviously, we change nylug to nycbug) However, replies to this post will have a To: line reading to poster A, so the rule above would miss that post. A slightly more complex rule, however, will catch it.

if (/^(From|To|cc|bcc): .*nycbug/)
        to Mail/IN-nycbug

These rules are case insensitive which is a Good Thing (TM) if you are a careless typist.

One can use Subject, From, or other header lines. The syntax is basically the same. If you are just using one thing in the header, such as From, To, Subject, etc, then it would be

if (/^Subject: .*linux/)
        to Mail/IN-linux

If you're using a slightly more complicated rule, trying to catch various parts of a header, like To, cc subject, etc then use the various keywords inside a second set of parentheses separated by pipes as in the nycbug example given above.

First the if, then the first parenthesis.
if (/^

Then the inner set of parentheses with the different conditions, separated by pipes.
if (/^(From|To|cc|bcc)

Then, finish the expression with the usual : .*whatever, close the expression--that is, type the final / and close the parentheses
if (/^(From|To|cc|bcc): .*nycbug/)

Aside from multiple header possibilities, such as including To, cc and the like, you can have other multiple conditions. If my friend John Paul Jones has three email accounts, all of which I want to go in a mailbox named IN-jones, I could have a rule like

if (/^From: (.*john|.*jpjones|.*jjones)/)
        to Mail/IN-jones

It's the same pattern. When there is more than one condition, put those multiple conditions in their own set of parentheses, separated by pipes.

: If you need all conditions matched, you can use &&. For example, I was getting a bunch of spam from noreply-<random-alpha-numeric-string>@plus.google.com. To make a filter that catches an email that has both noreply and plus.google.com in it
if (/^From: .*noreply/ && /^From: .*plus.google/)
    to Mail/googlespam

In this case, the entire expression is in the parentheses. Courier has a useful page here and there's another good syntax tutorial by swcp.com here.

Although it's sometimes simpler and less prone to error to make a few separate entries, one can combine various conditions. Like the nycbug rule given above, with FreeBSD-questions I want to catch multiple header possibilities. Also, some people send mail to questions@freebsd.org and others send it to freebsd-questions. So, the various multiple header possibilities go in one set of parentheses and the other conditions in another set of parentheses, all surrounded by the usual (/^ /).

if (/^(From|To|cc|bcc): (.*questions@freebsd|.*freebsd-questions)/)
        to Mail/IN-fbsd-questions

You might want to have a default personal inbox. In that case, after all the other rules put

if (/^To: john/)
        to Mail/IN-personal
I like to have a default box to catch anything else so at the bottom of my .mailfilter file I have

DEFAULT="Mail/IN-Misc"

Note that in this case, one quotes the path to the IN-Misc folder.

Note that maildrop stops when it hits a match, so put your most frequently used rules first, and the low traffic mailing lists towards the end.

If we want to run a command in our .mailfilter file, we can use xfilter. Say we want to send everything through spamassassin first. The top line of our .mailfilter would read

xfilter "/usr/local/bin/spamassassin"
Actually, the SpamAssassin docs recommend using spamc for filtering mail so the line would read
xfilter "/usr/local/bin/spamc"
(spamc is included with SpamAssassin--see man(1) spamc for more information.)

I sometimes use a despammed.com address--the only drawback to it is that they set [despammed] (in brackets as shown) in the subject line. This can be a nuisance, so again, I use xfilter to send a command to sed

xfilter "sed -e '/^Subject:.*\[despammed\]/s/\[despammed\]//g'"

Note that mailfilter should not have group or world permissions, so I set it read write for the owner.

chmod 600 .mailfilter

(One can also set it read only). For those who use SpamAssassin, you might want to put this rule at the top.

#Run everything through SpamAssassin first
xfilter "/usr/local/bin/spamc"
if (/^X-Spam-Level: \*\*\*\*\*/)
        to Mail/In-Spam

(This particular example is going to take anything with a score of 5 or higher and put it into a spam mailbox).

I find that after making a new .mailfilter file (or editing an existing one) it's a good idea to run getmail once with the -v (for verbose) flag. It will catch some (though not all) syntax errors in .mailfilter and also complain about some careless mistakes, such as allowing group or world permissions on the file. Sometimes, mailfilter won't work if the permissions aren't set to 500 or 600, though I haven't tested that enough to be sure.

To test mailfilter syntax, save an email to something like testmail.txt and then run, assuming your username is john
maildrop -V 4 -d john < testmail.txt

The other version of this is
cat testmail.txt|maildrop -V4 -d

You can increase the verbosity from -V4. Some articles suggest -V9.

The last thing we have to do is edit our .getmail/getmailrc file (or files if we have multiple accounts. At present the [destination] section reads
[destination]
type = Mboxrd
path = ~/Mail/IN-personal
unixfrom = True

We will change that to use an external program, in this case maildrop--in FreeBSD, it's in /usr/local/bin so my revised [destination] section will read
[destination]
type = MDA_external
path = /usr/local/bin/maildrop
unixfrom = True

(If you used procmail instead, change maildrop to procmail. Also, once again take note of maildrop's path on your system.)

(Back to Contents)

Reading mail

After you see that some mail has arrived open mutt by typing the command

mutt

Let's assume that I ran getmail with the -v flag and it indicated I received 7 messages. I'll open mutt and see a menu at the top. The messages, if no other rule covered them, went into my IN-Misc box. I then hit

c

(That's correct, just the letter c, to change directory)

I'll see a message

Open mailbox ('?' for list):

If I hit ? I will then see a list of my mailboxes. (The tab key also works) Although it doesn't tell me how many messages in each one, it will show a 0 in front of any empty ones. Then, I just use the arrow key (or vi commands, such as j and k) to highlight the mailbox that I want to examine.

If you set up mutt with mailfilter (or another filtering program) as mentioned above, everything will go into one mailbox or another. This does, on some distros and O/S's cause mutt to give an error message when opened, saying /var/mail/john: No such file or directory (errno = 2). This message is harmless, but annoying. (It may, depending upon distro and/or O/S say /var/spool/mail/john). To get rid of it, as root or with root privilege (in this case, we'll assume the message said /var/mail/john)

touch /var/mail/john
chown john:john /var/mail/john
chmod 600 /var/mail/john

You may also want to keep your sent mail in its own directory. In Gentoo, it automatically went to .maildir-sent, where it was listed by numbers. Finding a sent message in there was difficult. So, I would save all my messages to a directory in my .maildir called, obviously enough, SENT. To do this, I added the following to my .muttrc file

fcc-hook .*. ~/.maildir/SENT

In RH or FreeBSD it would be ~/Mail/SENT

This is sufficient for my needs. Some people prefer to divide their sent mail into different directories. If you wanted to do this you could insert a line like

fcc-hook "gentoo-user" "~/.maildir/gentoo-sent"

(Note that line would have to be added above the fcc-hook .*. which would catch anything not previously specified. With fcc-hooks it seems that the first rule, rather than the last is followed.)

One can also other things as the hook. For example, if I'm mailing a user that their mailbox is approaching quota, I want to save those emails in their own mbox. I have an fcc-hook of
fcc-hook "~s 'mail quota warning'" ~/Mail/quotamessages

As the reader probably guessed, the ~s refers to the subject. As the subject line has two words in this case, I put it within single quotes and the whole hook rule in double quotes. There are a variety of patterns like this which mutt understands, listed in man(5) muttrc.

(Back to Contents)

Keeping addresses

To keep a list of addresses in mutt is pretty easy. Once again, open up your .muttrc file and add these two lines

set alias_file=~/.mutt_aliases
source ~/.mutt_aliases

This tells mutt where to look for your aliases. This will serve as an address book. Now we create our .mutt_aliases file. Open your favorite text editor. Suppose that you want to have freebsd-questions@freebsd.org and gentoo-user@gentoo.org in your address book. You also have a friend John Smith who has the email of john@isp.com. You've been spoiled by Outlook Express, so you don't want to type the whole address--you want to be able to type free for freebsd-questions, gen for gentoo-user and John for your friend. We're going to put these three in our address book.

So, in our .mutt_aliases file we enter the lines

alias free       <freebsd-questions@freebsd.org>
alias gen       <gentoo-user@gentoo.org>
alias john  John Smith  <john@isp.com>

Now, if you open up mutt, and type m to send an email, if you type the alias in the the To: section, mutt will send it to the desired address. (You won't see this until after you've edited the message--at first, you would only see the alias that you entered). With the alias we did for John, if you type john in the To: section, it will expand to the John Smith that you have in the center. If you need to simply view your addresses, when you hit m and are given the To: line you can simply hit tab which will show your alias list--you can scroll down to the name you want and hit enter.

Also, if you're looking at an email and want to add the person to your address book, you can just hit a and mutt will take you through a dialog of creating an alias. Often, however, the last question will be save to file /.mutt_aliases? You will have to change that from /.mutt_aliases to ~/.mutt_aliases. The ~ refers to your home directory.

Recently, on a Fedora 15 installation, for whatever resaon, the a key wasn't mapped to the create-alias function. This can be fixed permantly by adding it to your ~/.muttrc or on the fly by first hitting a colon, : and then typing
bind a create-alias

The same line, if added to your ~/.muttrc, will then be in effect the next time you start mutt. You can also specify index and pager, as mentioned in the macro section, e.g., bind index a create-alias

Default keybindings can be seen by hitting ? while in mutt. For example, in this particular Fedora installation the term create-alias was there (which was how I reminded myself of the correct syntax) but no letter was visible. The mutt.org docs give a list of default functions.

(Back to Contents)

Replying to mailing lists

Some lists, such as most of the Gentoo linux and FreeBSD lists, are set so that if you simply hit reply, it only replies to the original poster, not the list itself. There are two solutions to this. Both have their advantages and disadvantages.

If replying to a post on, say, freebsd-questions, you hit g (for group) rather than r for reply, it will reply to the original poster and the mailing list.

As more people join the thread, this can result in a rather long list of addresses. Also, each person who has joined the thread will get a second, private copy of the email. This can be a Good Thing (TM) or a Bad Thing (TM). The good part is that many people, especially on a list as busy as FreeBSD-questions won't read every post on the list. They may not see a reply that is not personally addressed to them. Also, one will often see on such a list a note such as, "Please reply to me personally, as I am not subscribed to this list." The bad part is that some people might consider this extra private email a nuisance. However, as those who subscribe to such lists are usually quite aware of their format (and if not, quickly learn) its advantages can certainly outweigh the disadvantages.

Another disadvantage is that you might simply hit r for reply out of habit, and the email will only go to the people in the To: section rather than the list. Using g for group will solve this, if you remember, but again, this can wind up in a long list of addresses.

A simpler solution is to just hit L (in upper case) as in List. This will reply to the mailing list rather than any individuals. This works in mutt 1.5.19, and has probably been around for awhile. Prior to someone telling me about it, I always used the subscribe method, which I detail next. I first wrote this article in the early 2000's when it was necessary to use subscribe--I have no idea when it changed.

If just hitting L doesn't work on your version of mutt, add such lists to your .muttrc file. For example, I belong to a few FreeBSD mailing lists. They all end with FreeBSD.org. In my .muttrc I have the line

subscribe *freebsd.org

Now, if I reply to a posting on any of those lists and see no need for a separate, private reply to the poster, I simply hit

L

(Note that it's capitalized). This will now post my reply to the mailing list, rather than the individual.

(Back to Contents)

Using mutt with an LDAP address book

There are several methods that can be used to have mutt query an LDAP database. One very popular one seems to be lbdb. (Little Brother Data Base). Fedora supplies, in /usr/share/doc/mutt-<version>, a mutt_ldap_query script. There is also a mutt_ldap_query.pl perl script. (The Fedora one is a shell script, not perl.)

My personal favorite is bsdconsulting's mutt-ldap.pl. Unlike some of the others, it requires little editing to work with your LDAP server. It is designed to work with Exchange and/or Active Directory, but can easily be modified to work with any LDAP server. There are only a few lines that need editing.

Get the script from the above link (or use wget http://www.bsdconsulting.no/tools/mutt-ldap.pl from the command line.) Open the script in your favorite text editor and look for the lines
# --- configuration ---
$ldapserver = "domaincontroller.yourdomain.com";
$domain = "YOURDOMAIN";
$username = "myuser";
$password = "mypassword";
$basedn = "ou=companyxy,dc=companyxy,dc=tld";
# --- end configuration ---

Most of it should be self explanatory. As usual, we'll say the mail server is mail.example.com, the username is john and the password is 1234. Assuming that the LDAP schema for the company uses the ou of ourcompany, edit the lines above so that they read
$ldapserver = "mail.example.com";
$domain = "example.com";
$username = "john";
$password = "1234";
$basedn = "ou=ourcompany,dc=example,dc=com";

In some cases a company has a blanket user for the address book. If something like the above doesn't work, you can try changing the user to a more ldap like entry.
$username = "ou=Addressbook,dc=example,dc=com";

Note that the above assumes you have a more or less typical AD or Exchange LDAP setup. Other mail servers or LDAP schema may differ in which case you will have to edit according. For example, the CommuniGate Pro server has a simplified builtin LDAP schema where the base dn is simply cn=example.com. Hopefully, someone at your company knows the LDAP schema and can tell you what to use. For binding to the directory, (that is, authenticating the username to the LDAP server), mutt-ldap.pl uses the MS format. There is a line further down in the script which reads
$ldap->bind("$domain\\$username", password=>$password);

If your LDAP server uses a different form of bind (for example, many simply need username and password) you may have to edit that line as well. If it just needed the username and password, then that line would be changed to simply eliminate the "$domain\\ part, e.g., it would be changed to read
$ldap->bind($username", password=>$password);

In some cases, one has an LDAP server that doesn't require authentication to access the directory. In that case, just fill in the ldapserver and basedn fields and comment out the others. Also comment out the ldap bind line. Otherwise, though it will work, it will also give a message about an uninitialized value in the file.

In addition, one can edit the output. As it is written, it will say
1 entries found
jsmith@example.com	John Smith From Exchange LDAP database

You will see the following in the script towards the end
print($entry->get_value('mail'),"\t",
                      decode("UTF-8", $entry->get_value('cn')),"\tFrom
Exchange LDAP database\n");

The string From "Exchange LDAP database" can be edited or removed with no ill effects. I prefer to remove it entirely so that I just see the email address and name.

One could even edit it, reversing the decode("UTF-8) and ('mail') lines so that the name appears first. (Though I can't really see a reason to do that.) You can test that the script is working properly by running a query with it.
mutt-ldap.pl smith

It should give back John Smith's name and email.

Once you have edited and tested mutt-ldap.pl to your liking, move it to somewhere in your path. I prefer $HOME/bin--that is, the bin directory in my home directory, especially as it has information that I don't want to be world readable. Do a chmod on it to make it executable. For example
chmod 700 mutt-ldap.pl
mv mutt-ldap.pl /home/john/bin

Now, edit your .muttrc file. Add the line
set query_command="/home/john/bin/mutt-ldap.pl %s"

The %s at the end refers to a query string. This means that you will run the mutt-ldap.pl script, asking it to search for a string belonging to the name and/or email address that you request.
(For the complete beginner, a string refers to any group of characters).

If you haven't bound shift+Q to anything, it is the default macro for a query. In mutt, when you want to check the ldap database for an address hit shift+Q and you will see Query:

Type in part of the name and mutt will show you a list of matching addresses. Use the arrow key to highlight the desired address and mutt will use it.

If one wants to keep the address in their own ~/.mutt_aliases file, the following, admittedly very kludgy script will do it.
#!/bin/sh
mutt-ldap.pl $1 |sed -n '2p' |awk '{print "alias","\""  $2,$3 "\"""\t" $1}'

For newcomers it runs the mutt-ldap.pl command. The $1 refers to a variable, in this case, the name, for example, smith. As we've seen in mutt, this would return
1 entries found
jsmith@example.com	John Smith From Exchange LDAP database

The sed -n '2p' will print the second line. We then pipe it to awk, which will do the editing we want. We want "John Smith" in quotes here, hence the various "" with some escaped by \ to show awk that yes, we want these quotes printed in the output, they aren't being used in the command.

By default awk uses spaces as field separators, so we want the entry to read
alias "John Smith"	jsmith@example.com

This isn't an article on awk (for a very good one see Daniel Robbins' article on Developer Works) but basically we're inserting the word alias, swapping around what's printed out so that the name goes before the email, then putting in a tab between the name (in quotes) and the email address.

To put it directory into your .mutt_alias file you could add >> ~/.mutt_aliases to the end of the script so that it reads
mutt-ldap.pl $1 |sed -n '2p' |awk '{print "alias","\""  $2,$3 "\"""\t" $1}'>> ~/.mutt_aliases

(Be sure to use >>, not just >, otherwise you will overwrite your entire .mutt_aliases file. 2 >'s will add it to the end. A single one will echo it to the existing file, completely overwriting the file.)

Until you're sure it's giving correct output, run it once as shown in the first example, without a >> at the end, just to see what it will produce. Once you're happy with the output, you can start using it to add the addresses directly to your .mutt_aliases by adding the >> ~/.mutt_aliases at the end. Note that if your browser broke the lines, the entire line, beginning with mutt-ldap.pl and ending with ~/.mutt_aliases must be on one line.

It's certainly not necessary to do this if you trust your LDAP server, but it can save a few keystrokes if you have frequently used addresses in your .mutt_aliases.

Experienced shell scripters or perl programmers can no doubt come up with better solutions, the above is simply something I did in a hurry after deciding it would be useful.

(Back to Contents)

More details on multiple accounts

Let's say that our sample user john has a second isp. In this case, his user name is also john, with a password of 1234. The pop server is pop.example1.com and the smtp server is smtp.example1.com. His new email address there is john@example1.com John has one mailing list, mail@example1.com to which he has subscribed with the new acount.

In getmail-4.x he will have to create a separate rc file and specify both in the cronjob. So, his crontab would now read

*/5 * * * * /usr/local/bin/getmail -rgetmailrc -rgetmailrc2

My getmail page goes into more detail. He creates a second rcfile in his ~/.getmail directory, called getmailrc2. (In this case, it would be identical to the example given above, save that he would change the server line to read pop.server.example1.com.

In other words, he's getting his example1.com account sent to the same place on his machine--he's just telling getmail to poll a second server. Now, when getmail runs, it will poll both example.com's pop server and example1.com's server.

John wants everything going to a particular domain to use one header. For example, he belongs to mail@example1.com, mai12@example1.com and mail3@example1.com. He wants everything going to all these mailing lists to be sent through example1.com rather than his default of example.com He could make separate send-hooks for each list, however, he can also do it this way.

send-hook ".*.example1.com" "my_hdr From: John <john@example1.com>"

Now, all email going to example1.com, regardless of whatever is to the left of the @ sign will use the example1.com header.

The quick and dirty way is to simply hit

<esc>f

before sending the mail. That is, hit the escape key and f. This will allow you to edit the header and change the From: section of it.

There is another solution that will work better for individual emails rather than mailing lists. Say john sends some emails as john@example.com and others as john@example1.com Most of them are from example.com but on occasion, he wants to use the example1.com address. When he gets a response, he wants to respond with the same example1.address to which the email was sent.

He will add the following to his .muttrc

set reverse_name=yes
set alternates="john@example1.com"

Now, if he receives an email addressed to john@example1.com when he replies to it the From: portion of his header will read john@example1.com rather than john@example.com. If you have multiple addresses to use, they can separated by pipes such as

set alternates="john@example1.com|john@example2.com"

(I find that this only works if I write it as above, with no white space between word and pipe)

NOTE: As of mutt-1.5.6 alternates syntax has changed. Now, rather than the above it is

alternates "john@example1.com|john@example2.com"

In other words, remove the word "set" and remove the = sign.

Although I found, when setting it up, that it didn't seem to work with white space, since then, someone has written to say that

alternates ".*@domain1| \
            addr@domain2| \
            (a|b)@fake.domain1 \
            "

works perfectly for him in mutt-1.5.6i, which is, at time of writing, the development version.

The mutt wiki's section on multiple accounts gives a different syntax. Its version would read
alternates ^john@isp1\\.com$ ^johnisp2\\.com$

For those unfamiliar with regular expressions, also called regex, the ^ in front of john means that the address begins with john. The $ at the end indicates that the expression ends with com. The \\ before the .com is to escape the period in .com. (In most regexes, one only uses one backslash to escape special characters, but for some reason that I've forgotten, mutt requires two here.)

I've found that reverse_name can be iffy. If there are any send-hooks with my_hdr lines, it will override reverse_name. For example, if I open mutt, and the first email I send is to one of the FreeBSD mailing lists, I have a send-hook that uses example1.com. Now, I go to my personal mail and there's a letter from a friend that was sent to example2.com. Even though the send-hook with the my_hdr line shouldn't affect this second email, it will still use the return address of example1.com. The send-hook's my_hdr will remain in effect for any emails that I send until overridden by a different send-hook with a different my_hdr.

However, if I have two emails from two friends, neither of which have send-hook rules, reverse_names will work as expected. It's a bit odd and I am not yet positive that I haven't overlooked something in the man pages, but this rule seems to hold.

The my_hdr option itself is quite flexible. For example, if John wants to send mail from different addresses but have everything come back to john@example.com he could add the following to his .muttrc
my_hdr Reply-To: <john@example.com>

Now, unless over ridden by a particular send or folder hook, all emails will have the Reply-To: of john@example.com The same can be done for any field in the header, cc, fcc, and all the rest.

As mentioned early in this article, If you have two conflicting rules in .muttrc, it will often follow the last one. For example, on my work machine, I want everyone on the job to get emails from my work address so I have the following

send-hook "workdomain" "my_hdr From: Scott <workemailaddie>"

However, there are a few users with whom I exchange emails in the evening. While I can boot up my MS box and use our company's VPN, it's a nuisance. So, I wanted these users to reply to my home email addie, which can also be used at work. However, I put these rules above the previous rule, and it didn't work--I would have to set the reply-to manually. In other words if I have

send-hook "workuser" "my_hdr From: Scott <homemailaddie>"
send-hook "workdomain" "my_hdr From: Scott <workemailaddie>"

it won't work. The user will still get email from my work address. If I reverse it however

send-hook "workdomain" "my_hdr From: Scott <workemailaddie>"
send-hook "workuser" "my_hdr From: Scott <homemailaddie>"

it works the way I want it to work. The man page explains this, saying that if there are multiple matches for send-hooks, they will be processed in order. In other words, the final match will be the one that is used. As mentioned above, fcc-hooks seem to work in the opposite manner, the first one matched is used. There are also folder-hooks--like send-hooks, they are processed in order, so the last matching folder-hook is used.

You can also have multiple conditions in a hook. For example, if I want all email to example.com and example1.com to use a particular signature that I call SIG, I would do it this way.
send-hook "example.com|example1.com" "set signature="~/SIG"

I've seen posts where people say you can use ( example.com | example1.com ) however, in my experience, using parentheses gives me an error. Also, if I leave a space after the pipe (the | symbol) it doesn't work. In other words, if I do "example.com| example1.com" it won't work. I can do example.com |example1.com, and it will work. The important thing seems to be to have no space after the pipe character.

Don't forget that if you're using multiple accounts, you will have to add them to your .msmtprc. If we use the .msmtprc that we described in the first section
account examplecom
host smtp.example.com
from john@example.com

account default : examplecom

we would change it to
account examplecom
host smtp.example.com
from john@example.com

account example1com
host smtp.example.com
from john@example1.com

account default : examplecom

Then, we would add a send2-hook in mutt.
send2-hook '~f john@example1.com' 'set sendmail="/usr/local/bin/msmtp -a example1com"'

(Back to Contents)

A brief guide to colors in mutt

Assuming your terminal (whether console or xterm) supports it, you can put various colors into mutt. While there are a variety of things you can do, I'm just going to scratch the surface, and tell you how to color code your headers. So, once again, open up your .muttrc file. Add the following lines

color header brightred black ^from
color header brightblue black ^to
color header brightcyan black ^subject
color header brightgreen black ^date

This is probably self-explanatory, but in case it isn't

color header

this means that we're putting colors into the header.

brightred black

These are the foreground and background colors--obviously, you can change these to suit your taste

^from

shows what part of the header that you're looking to change. This is case insensitive.

If you do a bit of searching on google with the search terms colors muttrc you'll find far more that you can do with this, but the above should get you started. I'll just add a couple more. This one is from the RedHat default Muttrc file.

color status yellow blue

That will give you yellow text on a blue background when you first open mutt

This next one can be handy--it will put quoted text, from a previous message in blue

color quoted brightblue black

If you find that you see colors in console, but not in an xterm, then this can often be fixed with

export TERM=xterm-color

then calling mutt from that xterm.

A brief note on NetBSD. In FreeBSD, I use, rather than the word "black" the word "default." This won't work in NetBSD. Also, NetBSD's default console is vt100 while FreeBSD's is cons25. Doing in a sh shell or one of its derivatives (zsh, ksh, bash)

export TERM=cons25

in console will enable the colors. I've also found the oddity that in X, using rxvt, mutt won't use colors. However, if I do the same exporting of the Xterm to cons25 it works without problem.

With a recent (September 2004, I think) FreeBSD ports revision of mutt, I ran into another issue. As mentioned above, I would set the background to default. Suddenly, in console, rather than just the lines of text appearing in the desired color, on a black background, the text would appear to be more or less gray on a band of the indicated color. For example, if I have the From: line with red and default, there would be a red band running across the screen with the text in a grayish sort of color.

However, if I changed default to black, that caused a problem in X, where my rxvt terminal has a gray background. A minor annoyance, but an annoyance all the same. I solved it by making a silly script that will swap two .muttrc files back and forth, one with a black background and one with a default background. I only mention it here in case you run into a similar situation. (The silliness about it is in the prompts, such as "Change it?" If I type no then it echoes, "Ok fool, fix it yourself." I was in a bit of a whimsical mood when I wrote it.)

(This seems to be fixed as Feb. 2004, when upgrading to the latest FreeBSD port for mutt-devel. Using "default" for background now gives me expected output in console.)

(Back to Contents)

Spell checking

While this is not specific to mutt, it's handy to be able to check your spelling before sending an email.

If you use vim, which is often the default, you can just put
set spell<CR>

in .vimrc. This should automagically highlight misspelled words. You can toggle it on and off with a desired key, something like
:map <F5> :set spell<CR> 

in $HOME/.vimrc will turn on spell check and a second mapping in $HOME/.vimrc, using whatever key you desire, can be done for set nospell.
:map <F7> :set nospell<CR>  

If you're in insert mode, you do have to hit escape to change to editing mode for this to work, it doesn't work in insert mode. When, in editing mode, you do hit F5, (assuming that's the key you chose), you'll see :set spell on the bottom of the email (or other document being edited in vim) and it will go into effect, staying in effect when you go back to insert mode.

However some people dislike vim, and many FreeBSD people prefer the default nvi. For those who don't use vim, keep reading.

The program varies between systems but is usually ispell. Some systems use aspell. You can see which is the default with your system in /etc/Muttrc. CentOS' default /etc/neomuttrc shows that ispell is being used. If it is set to what you want in the default /etc/Muttrc, you don't need to add it to your $HOME/.muttrc. Actually, you don't need to add anything to your .muttrc or .neomuttrc as it's really taken care of by your .virc file. I mention it for completeness as the CentOS default neomuttrc has it.

Next, we're going to bind the F5 key to run it. So, open up .exrc or .virc, whichever you use and add

map <F5> :!hunspell %<CR>: e %<CR>

One thing to note here--that is exactly what you type, a less than sign, <, CR, then a greater than sign >. I didn't realize that would work (many thanks to Ian P. for letting me know, after seeing this page), and used to use ^M, for the carriage return.

In nvi, the default vi on FreeBSD, the syntax is a bit different. I'm not sure if you can get away with <CR> but I have found that trying <F5> doesn't work. I haven't tested in awhile, I've been using hunspell out of habit.

The ^M is actually a return character--in vi the way this would be done would be to hit ctrl+v and then the return key--you'll see a ^M in the file. Depending, it seems, upon system, you may have to do ctl+v ctl+M.

Either method works in vim, but Ian's is far easier to remember.

In FreeBSD, these days, this is what I have in my ~/.nexrc. This is on 12.2. I had to use the ^M method.
:map #5 :w^M:!hunspell %^M:e!^M^M

Now, when you want to check spelling, from command mode just hit F5 and hunspell will run.

(Back to Contents)

Mutt and GPG

Rather than reinvent the wheel here, I'm going to send you to Justin R. Miller's excellent guide. He has moved it from time to time, so I will include an example of what should be added to your .muttrc. Substitute OxXXXXXXXX with 0x(your public key). For example, if your public key is C9A4B311 substitute 0xXXXXXXXX with 0xC9A4B311. (The 0x--that is the numeral zero, not an upper case letter o--is a common prefix for hex numbers.)

If you cut and paste, be sure to turn off wrapmargin if you're using vi. The example below is for mutt-1.5. Your version of mutt may have slightly different syntax, depending upon whether you're using 1.4x, 1.5x. If the syntax is off, when you start mutt, you'll get a message, which will usually give the suggested replacement. (You can always check the system wide Muttrc for syntax. It will have a section on encrypting and signing that is usually commented out.) For example with mutt-1.4 I believe that the lines

set crypt_autosign=yes set crypt_replyencrypt=yes

were
set pgp_autosign=yes
set pgp_autoencrypt=yes
When I first upgraded from mutt-1.4x I would get a message that this was deprecated, and it gave the suggested replacement of crypt_autosign and crypt_replyencrypt.

Here are the lines from my .muttrc dealing with pgp, taken from Mr. Miller's example.

One important thing. The pgp_decrypt command used may be deprecated. Now that I use neomutt, (and this may be true for all newer versions of mutt, I don't know), the pgp_decrypt command should now read
set pgp_decrypt_command="gpg --status-fd=2 %?p?--passphrase-fd 0?  --no-verbose --quiet --batch --output - %f

rather than the version below. I'm leaving in the older version below for now, but if you get errors using it, such as could not copy message, or if you're using neomutt, use the line above.

I had some minor issues with the latest neomutt on FreeBSD-12.1. When I use the pgp_sign and pgp_encrypt_sign lines (which are also used in /usr/local/share/doc/neomutt/samples/gpg.rc) I would get errors such as unable to open pgp subsystem or unable to do in batch mode. However, using the lines given on neomutt.org's article about encryption, it worked again, even though there's no line in my .neomuttrc about signing. I do leave the rest of the pgp lines in, or it won't decrypt mail sent to you.

The neomutt site's lines are
set crypt_use_gpgme=yes
set postpone_encrypt = yes
set pgp_self_encrypt = yes
set crypt_use_pka = no
set crypt_autosign = no
set crypt_autoencrypt = no
set crypt_autopgp = yes 
set pgp_sign_as=0x12345678

With this FreeBSD-12.1 install I had to use that in my pgp section to get things to work.

I also had to create ~/.gnupg/gpg-agent.conf. It specifies the pinentry program used and just reads
pinentry-program /usr/local/bin/pineentry-curses

I'm not sure if this is a Just Me(tm) problem or not. Neomutt installs pinentry-tty as a dependency, but not pinentry-curses. However, if I use pinentry-tty as my pinentry agent, it doesn't work. I get the prompt to input my password in an odd place and the entire format of the email is off. So, you will have to install pkg pinentry-curses, create the gpg-agent.conf file as mentioned, and then reload the agent.
gpg-connect-agent reloadagent

This should print out OK and then a > prompt. At the prompt, type /bye and you're back at your terminal.

The stuff below, however is from Mr. Miller's site.
set pgp_decode_command="gpg %?p?--passphrase-fd 0? --no-verbose --batch --output - %f"
set pgp_verify_command="gpg --no-verbose --batch --output - --verify %s %f"
set pgp_decrypt_command="gpg --passphrase-fd 0 --no-verbose --batch --output - %f"
set pgp_sign_command="gpg --no-verbose --batch --output - --passphrase-fd 0 --armor --detach-sign --textmode %?a?-u %a? %f"
set pgp_clearsign_command="gpg --no-verbose --batch --output - --passphrase-fd 0 --armor --textmode --clearsign %?a?-u %a? %f"
set pgp_encrypt_only_command="pgpewrapng gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust --encrypt-to 0xXXXXXXXX -- -r %r -- %f"
set pgp_encrypt_sign_command="pgpewrapng gpg --passphrase-fd 0 --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust --encrypt-to 0xXXXXXXXX -- -r %r -- %f"
set pgp_import_command="gpg --no-verbose --import -v %f"
set pgp_export_command="gpg --no-verbose --export --armor %r"
set pgp_verify_key_command="gpg --no-verbose --batch --fingerprint --check-sigs %r"
set pgp_list_pubring_command="gpg --no-verbose --batch --with-colons --list-keys %r"
set pgp_list_secring_command="gpg --no-verbose --batch --with-colons --list-secret-keys %r"
set crypt_autosign=yes
set pgp_sign_as=0xXXXXXXXX
set crypt_replyencrypt=yes
set pgp_timeout=1800
set pgp_good_sign="^gpg: Good signature from"

If you mistype your passphrase then

ctl+F

will clear it, enabling you to retype it.

Outlook Express (and some other MS and Mac mail clients) may receive your GPG signed email as a text attachment. The mutt faq mentions this with the solution of tell them to get a non-broken email client, as it has to do with non-adherence to standards. There is a workaround with a patch and reconfiguration, but the one time I tried it, though it worked, it messed up some things with RFC compliant email clients.

Before sending, if you hit

p

then you will be given a gpg menu, allowing you to sign, (the default if one uses my example) encrypt, encrypt and sign, sign as or to forget it. If one hits

f

to forget it, it will be sent clear and unsigned. If sending to folks using Outlook Express or to mailing lists that strip non text attachments, one can hit

i

This will send the signature inline and is received as such by most mailing lists and Outlook Express.

Also, you'll find that if simply install gnupg when sending mail, you'll get a warning message that you're using insecure memory. This has to do with setting suid. (It's covered in the gnupg faq).
To fix it first find out where gpg lives.

which gpg

In FreeBSD it will be in /usr/local/bin, it may be elsewhere on your system. Assuming it is in /usr/local/bin

chmod 4755 /usr/local/bin/gpg

If you prefer the symbolic mode (using letters is the symbolic mode, using the octal numbers such as 4755 is the absolute mode), then the command is

chmod u+s /usr/local/bin/gpg

(Back to Contents)

Stupid mutt tricks

Many people like to have a random signature, using fortune or another program. (I use my own Buffy the Vampire Quote Generator but to each their own)

This is quite easy to do, but as the question comes up from time to time, it's probably worth including. One simply adds the following to their .muttrc

set signature="/usr/bin/fortune |"

Of course, one can substitute another program. If you need to combine it with a send-hook--for example, you only want it when you send emails to a particular friend, then the syntax would be (we'll assume your friend's email is jane@example.com)

send-hook "jane@example.com" "set signature='/usr/bin/fortune |'"

By default if nothing about a sig is mentioned in your .muttrc it will look for a file in your home directory called .signature. So, if you just wanted your signature to say Scott (which really only makes sense if it's your name, but you get the idea) you could simply do

echo Scott > ~/.signature

Then, without making any changes to your .muttrc all emails would end with

--
Scott

(The -- is the standard signature delineator)

Some folks like to have fun with my_hdr. For instance, by default, mutt has a User-Agent string that appears in the header. (In muttrc it's called user_agent. To hide it, you would put set user_agent=no in your muttrc.) To put something silly in there you would use
folder-hook . "my_hdr User-Agent:Jason Bourne"
Keep in mind that not everyone might have your sense of humor, so you might, rather than use the folder-hook . use send-hooks to your friends instead lest such silliness go to your boss, or a potential employer.
send-hook "my_friend" "my_hdr User-Agent: Austin Powers, man of mystery"

(Back to Contents)

Odds and ends

An error that I sometimes get is that a message can't be sent, exiting with error 127. This is usually because mutt can't find the smtp program that I have listed in my .muttrc. For instance, If I've installed msmtp in FreeBSD, it's in /usr/local/bin/msmtp. If I then copy my .muttrc over to a Linux box that has msmtp in /usr/bin/msmtp I'll get that error, the child 127.

Another one that happens if I forget to make changes in my .muttrc is with the editor. In FreeBSD, I have my editor set to /usr/local/bin/vim. (I need vim for it in order to do Japanese. For more info on that see my Japanese in Linux, FreeBSD and NetBSD page.).

If I then copy my .muttrc to a Linux box that has vim in /usr/bin, this will give me an error, as the Linux box won't have /usr/local/bin/vim. The error comes after I put in the subject line. It will say aborted unmodified message. If you get that message, chances are that somewhere your editor isn't specified correctly.

By default, if someone has formatted their mail differently than yours, a continued line will have a + sign in front of it, for example
  if I set my vi preferences to a shorter column width than
+someone else
it will have a plus sign on a continued line.

Some people find this annoying. To turn it off, add
set markers=no

to ~/.muttrc.

Another thing I picked up recently had to do with searching the SENT folder I have. The default seems to be searching the From rather than To field. In SENT, if I was searching for something, I wanted to look for the person to whom I'd sent the email. This required the following addition to my .muttrc

folder-hook SENT  'set simple_search="~t %s | ~s %s"'

Speaking of searching, if I want to search a folder for key words in a message, it's done this way. (This can be found by simply hitting a ? to get mutt's help)

Suppose I want to search my SENT directory for emails about samba. I open mutt, go to the sent folder then hit / and will see Search for:

I can then hit tilde and b (~b) and be asked for the search term. You can specify multiple patterns. For example, if I want to search for messages from john about samba, I can use
~f john ~b samba

I can then search the messages in that mailbox for the term.

Every so often, I like to clean out my sent folder. Let's say I have a thousand messages there, ranging from January 2004 through July 2004. Suppose I want to get rid of the first 500 of them. I can use tags. (I can also do this by just hitting D, (upper case) to delete messages matching the terms I use, but tags can add more flexibility, so we'll cover using them here.).

Note that in all the examples below, upper and lower case are important--if it's an upper case letter than type it as such.
First I hit

T

A message appears saying

Tag messages matching:

To choose by index number, that is, the number of the messages, and to select the first 500 I then type

~m 1-500

Now I hit

D

I then get a message

Delete messages matching:

I then hit

~T

for tagged messages and when I exit mutt, they will be deleted. Doing it by date is similar. Note that dates must be in the format DD/MM/YY, European style. If the month or year is left out, the current month or year is assumed. So, suppose I want to delete everything from January through June.

~T

Again I'm asked which messages I wish to tag

~d

I'm asked, surprisingly enough, which dates I wish to select

01/01/04-30/06/04

Then, as before, an upper case D for delete and all messages from January 1st, 2004 (01/01/04) to June 30th, 2004 (30/06/04) will be deleted. There are some variations on this--this page is aimed at the beginner so I'm only giving the most basic ideas. If you look at the mutt manual, usually available in html format in /usr/share/doc or /usr/local/share/doc and look at the tags section and searching by date, you can see a few shortcuts. As I mentioned, month and year, if not specified, default to the current month and year. One can, rather than giving the entire range of dates, simply indicate that everything up to a certain date or after a certain date should be selected. For example

-01/07/04

selects all items before July 1st, 2004. Doing

01/01/04-

selects all items after January 1st, 2004.

So, if I were really deleting all messages through June, my actual keystrokes would be (I'm leaving out the mutt prompt messages here

T
~d -01/07/04
D
~T

This would first tag all messages sent before July 1st, 2004, then delete them.

A ; (semicolon) will also indicate that you want to do something to all tagged messages. Suppose I have 3,000 messages in my SENT mbox. Now I wish to move the oldest 2,000 to a new mbox called ARCHIVE. I go into my SENT mbox and tag the first 2,000 as shown above, with T and then typing ~m 1-2000. Now, I type
;

I see
tag-

I type s for save. I will see
Save tagged to mailbox ('?' for list): =robert

(The =<name> will be the name of the first of the tagged messages, so if message number one was to robert, it would say =robert)

I backspace over the =<name> and type
~/Mail/ARCHIVE

(If I just type ARCHIVE, it will create a mbox ~/ARCHIVE rather than ~/Mail/ARCHIVE. In this case, I want to save it in my ~/Mail directory.) It will ask
Create /home/<username>/Mail/ARCHIVE (yes/no)

The username being, obviously, my user name. If we stay with our example of john, it would say /home/john/Mail/ARCHIVE. I hit y for yes, it will copy the messages. When I exit, mutt will ask if I should delete the 1000 messages. If I hit yes, it will remove them from the SENT mbox.

As you can see, tags are quite handy.

Much of this can also be done without tags. For example, rather than tagging and then deleting, one can just do
D 

and will then get a prompt
Delete messages matching

At that point one can use ~d -01/09/10 to specify deletion of all messages older than September 1st, 2010, or any other pattern such as ~m for messages, a date range, or almost any of the patterns that we've already discussed. Note that you use an upper case D to signify deleting a match---a lower case d will just delete the current message.

Sometimes, one wants to resend a message, either to edit it, or send to someone you forgot to cc or whatever. If you open a message, say from the SENT mailbox, and wish to resend it as a new message hit ESC e. This will resend it as a new message.

The folder and send hooks are incredibly flexible. For instance, suppose that you wish, whenever you are in the freebsd-stable mailbox, that any message you send while browsing that mailbox goes to the freebsd-stable mailing list. (Hopefully, you know that one does not thread-hijack--that is, you don't take an email sent to a mailing list, simply change the subject line and hit reply. That messes up anyone who views messages in a threaded format, as it doesn't really change the header information. For a quick explanation of this, see a Faq I have for *nix newcomers.).

You can create a folder-hook entry in your .muttrc

folder-hook freebsd-stable "my_hdr To: freebsd-stable@freebsd.org"

Now, if you are browsing messages in your FreeBSD-STABLE mailbox, and hit m to create a new message, it will automatically be addressed to freebsd-stable@freebsd.org.

(Back to Contents)

Newer (and some older) odds and ends

For awhile, there was a fork of mutt called muttng. As far as I know, it's been discontinued, but I believe all the features mentioned below are available in mutt 1.5.x.

In June, 2018, there is neomutt, which includes many extra patches, such as the sidebar, which is now accepted upstream. It can use your existing $HOME/.mutt* files, and feels a little snappier to me.

The side bar is a fun little thing, but I got tired of it quickly. Neomutt has a page with some sample defaults. You will need to add a line mailboxes = with a list of mailboxes you want to be visible. Something like
mailboxes = /home/scottro/Mail/IN-personal /home/scottro/Mail/IN-Misc

I also find it useful to change the default of set sidebar_short_path = no to yes. This way, in the sidebar, it will just show IN-personal and IN-Misc, whereas otherwise, it will show the entire /home/scottro/Mail/IN-personal and so on.

The other option, shown in a another part of their howto is to use
set folder = "~/Mail"
mailboxes =IN-personal IN-Misc 

Here's a fairly simple sidebar setup. (The one they give is good, but perhaps overkill for our needs.
set sidebar_visible = yes
set sidebar_width=14
set sidebar_sort_method = unsorted
set sidebar_delim_chars='       /.'
set sidebar_folder_indent=yes
set sidebar_short_path=yes
macro index B 'toggle sidebar_visible'
macro pager B 'toggle sidebar_visible'
macro index b 'toggle sidebar_visible'
macro pager b 'toggle sidebar_visible'
bind index,pager \Cp sidebar-previous
bind index,pager \Cn sidebar-next
bind index,pager \Co sidebar-open
set folder ="~/Mail"
mailboxes =IN-personal IN-Misc

This uses shift+b to toggle visibilty, ctl+p for the previous sidebar entry and ctl+n for the next one. To open a mailbox from the sidebar use ctl+o.

From mutt 1.5.x lines in the .muttrc file dealing with pgp have to be changed. If not, you'll get error messages, (although it should still work, if I remember correctly, these lines are just deprecated, not yet removed).

I have suggested above that the reader use Justin Miller's file. It has the lines

set pgp_autosign=yes
set pgp_replyencrypt=yes

These two lines should be replaced with

set crypt_autosign=yes
set crypt_replyencrypt=yes
Another handy mutt trick is if you need to send an attachment from, for example, a shell script. The mail command can do this of course, but it's rather non-trivial. With mutt, suppose you had to send john@example.com a document called file.doc. If you are going to send that without any message, and the subject line of "attached docs" the command would be
mutt -a file.doc -s "attached docs" john@example.com

If you wanted to send the message, message.txt to john as well, the command would be
mutt -a file.doc -s "attached docs" john@example.com < message.txt

If you get an error like unable to attach file separate the recepient's address with double dashes and a space for example
mutt -a file.doc -s "test" -- john@example.com

Another way is to just make sure the attachment is at the end of the line, for example
mutt -s "test" john@example.com -a file.doc

This doesn't seem to work completely non-interactively--it will open a window with the address you specified, and require some keyboard input, going to the compose window (even if you have already specified a textfile for input) and requiring :x or :wq before getting to the send screen, where you manually have to send. I haven't yet found a way to completely automate it.

To attach a file when using mutt normally (as opposed to the method above with a script) simply hit the "a" key (without the quotes.) You will then be asked for the name of the file you want to attach. If you change your mind about the attachment before sending the email, highlight the attachment and hit D for detach. As always in Unix, case is important and this has to be an upper case D.

Sometimes, for example, at a job where everyone else uses Outlook, and includes images inline, you may want to do this with mutt. The world is changing and most people use html mail. I'll avoid my rants on this, and simply mention that if you want your attachment in line, rather than showing as an attachment, you can do this. After having hit a for attach, and seeing the file name (with an A to its left, to indicate that it's an attachment, hit ctl+d. This, in composing mode, will "toggle disposition" meaning it will change a mime type from attached to inline. You will see the A change to an I, and the attachment will now appear to the viewer as part of the email, rather than an attached file. I haven't figured out a way to get it to appear above the signature, however--it will appear below your signature.

That's about it. The above only serves as an introduction, but gives you an idea of how to get started with mutt.

The Mutt online manual is an excellent next step. It's also usually available in /usr/doc/ or /usr/local/share/doc in FreeBSD.