In this article I’m going to be long-winded and describe my story. If you want to skip straight to the solution summary, I won’t hold it against you :)

The Problem

So, you want to use Pine with maildir, eh? You’ve heard a lot of good things about maildir, and want to move from using your local mbox files to maildir. You’ve even already already converted your mbox to maildir using scripts that are available. (If your situation was like mine, you also might have run out of inodes on your filesystem when you created a file for each message, because you setup your filesystem with too many bytes per inode and didn’t know how to use df -i when it told you the disk was full, even though you had oodles of GB left, and left you thoroughly confused for quite a while. You then had to reformat your filesystem so you could get more inodes. But that’s another story.)

But Pine doesn’t support maildir. At least the official distribution doesn’t. There is a patch available, but when you tried it, you found it that while it works for simple stuff, you can’t seem to copy messages from one folder to another (seemingly because Pine assumes the target folder is an mbox). Another problem you run into is that you can’t seem to use it for your sent-mail or postponed-msgs folders.

So what is a poor soul supposed to do? You’re a stubborn geek, and you’re determined to somehow get get Pine to work with maildirs. Besides, you’ve already converted your mboxes to maildirs, and don’t want to convert back!

My Story

Well, I had the same frustrations as you. I soon realized that Pine wasn’t going to handle maildir well with the patch. So I though, “Why not just use imap over the localhost?” So, I went and installed the Courier IMAP server, and told it to only bind to 127.0.0.1 (localhost). It seemed like I was going along okay; by adding a layer of abstraction to the mail (through IMAP instead of through a maildir driver), this seemed like progress.

In order to get Pine to talk IMAP, in my configuration I changed my inbox-path to {localhost}INBOX, my default-fcc to {localhost}INBOX.sent-mail, my default-saved-msg-folder to {localhost}INBOX.saved-messages, and my postponed-folder to {localhost}INBOX.postponed-msgs.

But two things were uncool as the situation stood. First, I was still going over a network connection (which does slow things down), and second and more importantly, Pine wouldn’t remember my passphrase. A little searching on Google turned up an interesting hit, though. It seems that Scott Leibrand wrote up a nice article describing how you could get Pine to talk IMAP through ssh. Since you can authenticate with ssh using public keys, this meant that you could setup your ssh authorized_keys properly, and have Pine connect to the localhost through ssh, and talk IMAP, without having to enter a passphrase every time. Even though the article describes how to use it with UW-IMAPd, it seemed like it should also work for Courier. That is, Courier’s imapd can also be run so that it simply reads and writes from stdin/stdout.

But there seemed to be a problem; Pine kept complaining with something like “Unexpected response: INFO”. Another Google hit seemed to suggest something; the INFO line that Courier’s imapd is stderr, not stdout. So, I made it so that the program that Pine execs over ssh my script courier-imapd-noerr:

#!/bin/sh

umask 0077
cd $HOME && /usr/sbin/courier-imapd .maildir 2>/dev/null
    

Woohoo! This worked! I seemed to be at my journey’s end; I didn’t even need my courier-imapd server running anymore; sshd was the the only service listening on my network interfaces.

But then I hit a bit of inspiration: why am I even bothering to do this over ssh at all? Pine doesn’t know it’s running over ssh; it’s just dealing with the stdin and stdout of what it things is ssh. Instead of having Pine run ssh and then exec on the remote end courier-imapd-noerr, why not just run courier-imapd-noerr straight? By setting in my ~/.pinerc ssh-path=/home/ftobin/bin/courier-imapd-noerr, Pine would talk IMAP without even having to open a network socket at all, never mind ssh!

And it works lovely now. The only issue is that it can be very slow for Pine to do perform mass operations on mailboxes now, such as delete 2000 messages at a time. But this is rare, and I can just go into the maildir itself and do things by hand if I need to. For me, that’s one of the beauties of having filesystem-level data structures: you can go in with your own tools easily and do powerful operations that your normal client (e.g., Pine) can’t or won’t do well.

One more thing: in the folder list, each folder shows up as folder and .folder. Thanks to Michael Weishaar, the solution to this irritant is to enable the Pine option quell-empty-directories. I recommend reading the help associated with this option, as there may be surprising side effects.

Solution Summary {#summary}

  1. Install the Courier IMAP server.
  2. Create a script similar to my courier-imapd-noerr, with the appropriate paths changed.
  3. Set the following options in your ~/.pinerc, with appropriate paths changed:

    inbox-path={localhost}INBOX
    default-fcc={localhost}INBOX.sent-mail
    default-saved-msg-folder={localhost}INBOX.saved-messages
    postponed-folder={localhost}INBOX.postponed-msgs
    ssh-path=/home/ftobin/bin/courier-imapd-noerr
    folder-collections=localhost {localhost}INBOX.[]
    
  4. Set the Pine option quell-empty-directories (be sure to read the help!).

  5. Convert your mboxes to maildirs with Courier’s maildirmake and one of the many scripts available.