I have tried Mail, Sparrow, Airmail and have now returned back to Mutt with my tail wagging between my legs, because they all sucked.
I first spend some time cursing and fighting with postfix mail transfer agents. So fuck it… I am going try simpler alternatives first and work it up from there.
The build of Mutt that I am playing with at the moment offers support for
sending and receiving mail without having to set up any other tools. In order
to quickly get moving let’s first examine how we can get a Mutt setup
running without any extra bells and whistles. Without further ado; the simplest
~/.muttrc that would be of any use to me:
set from="firstname.lastname@example.org" set realname="David Asabina" #set sendmail="/path/to/msmtp" set use_from=yes set envelope_from=yes set imap_user="email@example.com" set imap_pass="`gpg --quiet --for-your-eyes-only -d ~/.mutt/vidbina.gpg`" set smtp_url="smtp://firstname.lastname@example.org@smtp.gmail.com:587/" set smtp_pass="`gpg --quiet --for-your-eyes-only -d ~/.mutt/vidbina.gpg`" set folder="imaps://imap.gmail.com:993" set spoolfile="+INBOX" set postponed="+[Gmail]/Drafts" set sort=threads set editor=vi source ~/.mutt/colors
Consult Andrew’s Mutt tutorial in order to get colors set up on your configuration.
The passwords have not been entered into my
muttrc in plain text but are
decrypted using my private key setup on my box. This requires you to get GPG-ed
up. I have dedicated another post to explaining the GPG basics (the internet
already has plenty of wonderful resources regarding this too).
Speed Things Up by Caching
The problem with the simple setup described above is that it requires a connection to the IMAP server in order to be of much use to you. Mutt, being the powerhouse she is, obviously knows a trick or two to resolve that.
With caching enabled we will be able to cache the headers
and/or messages on our local box by simply setting the
set header_cache=~/.mutt/hdrs set message_cachedir=~/.mutt/msgs
Although caching speeds things up it’s is not really the solution for the travelling hacker. We need to be able to use Mutt while offline too.
Now that there is a working mutt setup one could finetune stuff. For one
Mutt’s native IMAP implementation performs IO somewhat in a blocking
fashion which freezes up the pup when the connection dissapears. This means
that it may be time to use something like
avoid the Mutt quicks.
Sending mail with
For sending emails one may use msmtp, ssmtp, sendmail but based on the one the
frustration it just caused me I have decided to listen and go for something
simple first. Mind you that
msmtp does not offer offline
mailing out of the box, we will have to setup a queue for
msmtp if we
would like this privilege, but having
msmtp running is a start.
brew install msmtp
In order to get
msmtp ready to roll we will need to point it to the CA
bundle on our mech. I have used Adrew’s instructions to build my own
pack of certificates stored into the path
defaults tls on tls_starttls on tls_trust_file ~/.certs/ca-bundle.crt logfile ~/.mutt/msmtp.log account vidbina host smtp.gmail.com port 587 protocol smtp auth on from "email@example.com" user "firstname.lastname@example.org" passwordeval "gpg --quiet --for-your-eyes-only --decrypt ~/.mutt/vidbina.gpg"
We could call msmtp with the
--serverinfo flag to confirm the settings
make a bit of sense. In my case a prompt appears for my passphrase while GPG
attempts to decrypt my SMTP password, subsequently followed by some of the
server details of the Google server that manages my mail.
msmtp --serverinfo -a $ACCOUNT
Mutt does not allow us to run any tools that demand terminal input from the
user. Which means that the passphrase prompt will not bode well with the
canine. In order to mitigate this issue we could use
gpg-agent to cache
the token for later use. The agent would then make sure that the
call is provided the proper passphrase and carries on its simple chore.
Lets first ensure that the
passwordeval line no longer
hooks up to a terminal for possible input by changing the last line to
passwordeval "gpg --quiet --no-tty --for-your-eyes-only --decrypt ~/.mutt/vidbina.gpg"
In order to remember the passphrase we should see to it that the
~/.gnupg/gpg.conf file contains the
# Some line in the gpg conf file use-agent
Furthermore we will need to ensure that our box knows how to fire up the
gpg-agent when necessary. The agent needs to know which terminal to work with
and furthermore it will need the
GPG_AGENT_INFO variable to be set.
By appending the following lines to our shell’s
*rc file or
~/.*_profile we can set the
GPG_TTY (terminal), export it and
also set the
SSH_AUTH_SOCK variables if this
information is available.
GPG_TTY=$(tty) export GPG_TTY if [ -f "/tmp/.gpg-agent-info" ]; then . "/tmp/.gpg-agent-info" export GPG_AGENT_INFO export SSH_AUTH_SOCK fi
The previous addition to our shell’s configuration depends on the
/tmp/.gpg-agent-info file. When starting the
gpg-agent it is also
possible to instruct the agent to create the needed file by
telling the gpg agent to fire up using the following command:
gpg-agent --daemon --enable-ssh-support \ --write-env-file "/tmp/.gpg-agent-info"
With this setup we will be able to have
msmtp handle our mailing while
keeping passwords very secret. There will be no need to enter the passphrase
every time gpg gets going. If you do need to enter the passphrase, because
maybe the cache has expired, you will be prompted by a nifty fron-end to
enter the passphrase. This does not interfere with Mutt. The only requirement
gpg-agent is running.
Note that the terminal used by the gpg-agent stays the same untill the agent is setup to use another terminal session. This means that you would have to return to the terminal session within which the agent was setup.
Queing outgoing e-mail
msmtp and mutt play ball :ball: it becomes
time to consider how to deal with outgoing messages when the connection is not
Mutt has some ability to retrieve mail but since it wasn’t quite designed to work in a multi-threaded manner large mail-retrieval jobs may render Mutt unresponsive until retrieval is completed. Tools such as offlineimap allow for the retrieval of e-mail through cronjobs or manual terminal runs that have no impact on the responsiveness of Mutt.
With offlineimap installed, retrieval becomes as simple as running
offlineimap from a terminal.
As knowing how to operate Mutt is generally down to knowning the
keybindings, I have listed some of the most important bindings in the
sections below. The command to the help page should be listed as the last
property in the topbar when Mutt is open which happens to be
? in a
default Mutt setup.
Basic Navigation (from Index)
||half page down|
||half page up|
Basic Actions (from Index)
||group reply/reply to all|
||forward higlighted message|
||Copy to folder|
At some places I will refer to Mutt functions in italics in which case one should be able to find that entry as a literal string in the second column of the help page. Let’s assume that I refer to the Mutt command search which is printed in italics. You can
/to start searching (by default
/should be bound to the search command) then
- type the italicized string (
searchin this case) followed by
and Mutt should get you to the line that explains it all (1st column is the
keystroke, 2nd column the command name and 3rd column represents a description
of the feature) :wink:.
You could repeat this search by pressing
n which is bound to search-next by
Mutt allows you to quickly perform some operations on batches of emails that would have required multiple clicks with other clients. In order to get this trick it is absolutely convenient to be aware of the different patterns and the tagging functionality of mutt.
Archiving tagged messages
One could tag messages by stepping through the list page and tagging individual
messages using the tag-entry function (bound to the
t key, if you sport a
default Mutt setup).
One can save a message to the archive by entering
s is bound to the save-message command in the default configuration
Mutt’s save actualy writes a message to the destination and removes it from the source location. In that regards save is more like a typical move command while Mutt’s copy command actually writes to the destination and keeps the original in its source location.
Since we do not only wish to save the message upon which the cursor
rests but all tagged messages I prepend the archive command with the
tag-prefix operator (which is bound to
; in the default Mutt setup)
in order to have the command apply to all tagged messages.
Up next I demonstrate the usage of different patterns in tagging messages. Perhaps you will choose to archive, perhaps you just want to delete, or maybe even forward. Mutt can do it all :email:
Tagging messages older than 60days
The tag-pattern command (default
T) allows us to tag multiple
messages using a pattern in comparison to tag-entry command (default
that only allows us to tag the message at the cursor.
~d pattern allows us to specify date conditions and in the next example
I use these features to tag all messages with their date greater than 60 days.
Obviously I could perform some operation on all these tagged messages as demonstrated in the previous example :wink:.
Tagging all messages from facebook
~f pattern allows us to define a pattern for the sender. If we simply
want to tag all messages coming from Facebook we could use the following
Tagging all messages with certain keywords
In this example I check for message content and want all messages that contain any of the following keywords facebook, twitter, instagram, vimeo or youtube to be tagged.
View open message in browser
Many of the messages that I receive are formatted in HTML. Mutt fortunately can pipe your messages into any viewer/pager/browser of your choice (provided you can pipe data into it).
By default Mutt has
| bound to the pipe-message command which would allow
me to pipe my email into w3m for easier viewing
|w3m -T text/html
Forward Messages with Attachments
<Esc>e combination triggers the
command. There is probably a better way to do this, but it works well enough in