Update: Ryan Lue pointed me to his little_red_flag daemon which triggers mbsync synchronization if changes happen both locally and remotely. Try it out!
A lot of people recommend OfflineIMAP for syncing mails between a remote IMAP account and a local maildir mailbox for mutt1 pleasure. However, OfflineIMAP’s quality is far from what I think is necessary for a tool handling sensitive data such as mail. Looking for an alternative, I stumbled upon mbsync which was maintained by Ted Ts’o for a while. Setting it up to synchronize with the Google mail servers is pretty simple once you know the quirks of Google’s IMAP implementation and mbsync’s weird configuration approach.
To get it working with Google I had to compile mbsync from source — the
packaged version didn’t work for me. mbsync just wouldn’t download any mails.
So, go ahead, download the mbsync source and
configure && make && make install
it. mbsync groups its
.mbsyncrc configuration into account details, stores and
channels that connect stores for synchronization. A typical GMail account would
look like this:
IMAPAccount gmail Host imap.gmail.com User firstname.lastname@example.org Pass secret UseIMAPS yes CertificateFile /etc/ssl/certs/ca-certificates.crt
Saving the password plaintext is not the best idea. Fortunately, the latest
mbsync sources come with the
PassCmd setting, which is just a command that is
run in a subprocess of mbsync. With a tiny Python script such as this:
#!/usr/bin/env python import argparse import keyring import getpass if __name__ == '__main__': SERVICE = 'mbsync' parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group(required=True) group.add_argument('--set', '-s', type=str, help='Account to save password') group.add_argument('--get', '-g', type=str, help='Account to get password') args = parser.parse_args() if args.set: password = getpass.getpass() keyring.set_password(SERVICE, args.set, password) else: print(keyring.get_password(SERVICE, args.get))
PassCmd set to:
PassCmd "imap-pass -g email@example.com"
we have a relatively secure way of retrieving the login password through our system’s keyring. Now we have to define a proxy store for the IMAP account and a store for our local maildir
IMAPStore gmail-remote Account gmail MaildirStore gmail-local Path ~/mail/gmail/ Inbox ~/mail/gmail/INBOX
To sync between those stores, you have to set up a channel. Most options are
self-explanatory, however you must take care to use the correct label names for
the sent, draft, starred etc. mail. The names depend on the language set in the
web interface! For me, the verbose flag
-V came in handy because this displays
the communication with the IMAP server, including listing all the available IMAP
Channel gmail Master :gmail-remote: Slave :gmail-local: Patterns "INBOX" "[Gmail]/Sent Mail" "[Gmail]/Drafts" "[Gmail]/Starred" Create Both Expunge Both SyncState *
mbsync gmail syncs mail on the Google servers with your local
I wanted to write a post about mutt for quite a while now, but I am not ready with my configuration nor do I have much time to document my progress. Hence, I will present different aspects one by one. ↩