mutt with offlineimap

<agriffis> I don't have a website yet that shows my mail setup.
I should make one sometime. mutt, offlineimap, courier-imap, mailcap_bg, mailcap, mailout, xmutt, outq, etc.
<Chouser> agriffis: I'm curious about that too, now that you mention it. I'll have to create another email setup at this new job, so I'd like to know roughly what you're doing and why.
Now would be good. ;-)

In a nutshell, I use offlineimap, courier imap and mutt to get the following benefits:

  • complete offline access to mail, including folders and sending new messages. Everything is sync'd the next time it's possible.
  • all mail is replicated between the imap server(s) and workstation(s). For my personal setup, there are 4 imap servers and 3 workstations involved, but this can scale up or down as needed.
  • mail can be accessed directly from the imap server(s) without worrying about losing anything; the workstations will catch up the next time they sync.

offlineimap

The cornerstone is offlineimap. This is a beautiful program written by John Goerzen, the author of Foundations of Python Network Programming. Offlineimap does a two-way synchronization of local maildirs to a remote imap server. For example, if your mail is currently stored on an imap server, the first run of offlineimap will create a local image of your inbox and other folders. The next time you run offlineimap, any changes you have made locally will be propogated to the server, and any changes on the server--including newly arrived mail--will be propogated to your local maildirs.

Offlineimap is safe to run on multiple clients simultaneously, so you can have more than one machine with all your mail stored locally. Personally I have 3 machines on which this is done: my laptop, my home workstation and my alpha workstation at the office.

Offlineimap can also synchronize against multiple IMAP servers, so you can have more than one mail account on your local machine. Personally I synchronize against 3 incoming servers (hp's imaphub, gentoo's dev.gentoo.org, and griffis1.net). For outgoing mail, I syncronize against 2 outgoing servers (my alpha workstation "kaf" at hp and griffis1.net for personal and gentoo mail). Ideally you'd use the same outgoing servers as incoming servers per account, but if you don't have configuration access to the outgoing servers, it sometimes isn't possible.

My offlineimaprc (available below) contains examples for interacting with cyrus imap, courier imaps, and courier imap over ssh.

Note: One oddity of offlineimap is that it isn't possible (yet) to create new folders locally and have them propogate to the imap server. This is because offlineimap only pays attention to the folder list from the server. So to create a new folder (or remove an old one) you need to either access the imap server via "mutt -f imap://..." or ssh to the imap server and create/remove the appropriate maildirs.

courier imap

My personal setup accesses both courier imap and cyrus imap servers, but outgoing mail only works with courier imap. That's because courier provides an outbox feature; any message saved to the output is automatically sent via smtp. This makes it possible to store messages in a local outbox, then have them send automatically the next time you synchronize with the server.

There are two ways to activate courier's outbox feature. If you're accessing the imap server via imap protocol (or imaps), then you need to configure the imap server via /etc/courier-imap/imapd, in particular the OUTBOX and SENDMAIL variables. If you're accessing the imap server via ssh, then you should activate it like this in .offlineimaprc:

[Repository outbox_repository]
type = IMAP
preauthtunnel = ssh -q my.mail.server \
    'env SENDMAIL=/usr/sbin/sendmail OUTBOX=.Outbox /usr/sbin/courier-imapd .maildir'
nametrans = lambda foldername: re.sub('^INBOX.', '', foldername)
folderfilter = lambda foldername: re.search('Outbox', foldername)

mutt

A little configuration can go a long way to making mutt interoperate well with offlineimap. Here are the snippets I use that are relevant for offlineimap and/or maildirs. More hints in my full muttrc (available below).

  • Offlineimap only supports maildirs. Of course, you can use whatever format you want for boxes that won't be synchronized, but maildirs aren't a bad choice in any case.
    set mbox_type=maildir
  • If you want to use courier's outbox feature, there are a couple possibilities for depositing outgoing mail in the outbox. First possibility is to use a script in place of sendmail, something like this:
    set sendmail=~/bin/mailout
    set sendmail_wait=0
    
    This is how I used to do it, and I'd still recommend it for the sake of simplicity. If you'd like to know what I'm doing now, I blogged about it: part one and part two.
  • Easy method to set list of mailboxes based on what exists. Only caveat is that this only runs when mutt starts, so it won't pick up any mailboxes that offlineimap creates while mutt is running.
    # My mailboxes, inboxes first
    mailboxes \
      +hp/INBOX \
      +g1/INBOX \
      +g2/INBOX \
      `cd ~/mail; find hp g1 g2 -type d -maxdepth 1 -mindepth 1 \
        ! -name INBOX ! -name Outbox ! -name Trash ! -name postponed ! -name sent \
        -printf "+%p "`
    
  • Macros for invoking offlineimap from mutt. I used to do this from cron, but discovered I like having complete control over when it runs.
    macro index \cf "<shell-escape>offlineimap\r"
    macro index \ef "<shell-escape>outq -f\r"
    folder-hook 'hp/' 'macro index \cf "<shell-escape>do_offlineimap -a WorkRecv\r"'
    folder-hook 'g1/' 'macro index \cf "<shell-escape>do_offlineimap -a HomeRecv\r"'
    folder-hook 'g2/' 'macro index \cf "<shell-escape>do_offlineimap -a GentooRecv\r"'
            

other stuff

In addition to the big stuff described above, you'll also find below:

  • mailout: replacement for sendmail that places outgoing mail in the appropriate outbox. This is written in ruby; hope that doesn't scare you off! Note: mailout depends on safecat, so don't forget to emerge that.
  • outq: this program shows me what's in my outboxes waiting to be sent, similar to mailq. It can also flush outgoing messages when invoked with -f (see mutt bindings above).
    $ outq
    g1/Outbox/new/1100147273.M461251P13763.mustard
            Message-ID: <20041111042743.GA13745@mustard.flatmonk.org>
            Date: Wed, 10 Nov 2004 23:27:43 -0500
            From: Aron Griffis <agriffis@gentooo.org>
            To: Aron Griffis <agriffis@gentooo.org>
            Subject: demonstrating outq
        

Downloads

Filename
bin/mailout
bin/outq
muttrc.in
offlineimaprc

This page was generated Tue Jan 29 07:57:04 2008.