Listing Mailboxes

How to list mailboxes is one of the most confusing problems with IMAP. When you're implementing your solution, keep this in mind all the time:

This basically means that you should avoid using "*" LIST wildcard. Instead show only the mailboxes that user has expressed interest in. Most clients show mailboxes as a tree structure. Typically you begin by displaying only the toplevel mailboxes:

1 LIST "" %

If some of the mailboxes have children (see the children section below), get a list of them only after user has opened that hierarchy in the tree:

2 LIST "" work/%

Don't expand automatically the whole tree. That's even worse than executing LIST "" *.

Hierarchy separators

All the toplevel mailboxes in a namespace have the same separator. So a single LIST command can never return different separators, with the exception of INBOX which is a special case. INBOX exists in a namespace of its own, so it (and its children) may have a different separator than the rest of the mailboxes. You rarely see this though, except as a NIL separator for INBOX with UW-IMAP.

If you need to know the hierarchy separator, you should get it from a non-INBOX LIST reply if you've already done LIST. If you don't see any non-INBOX mailboxes or you don't need to do LIST for any other reason, you can get the separator for default namespace with:

1 LIST "" ""
* LIST (\Noselect) "/" ""
1 OK

If you want to get it for other namespaces, use:

1 LIST #shared/ ""
* LIST (\Noselect) "/" "#shared/"
1 OK

Some clients cache the hierarchy separator forever. This has problems if the server configuration is changed (e.g. server software changed). Try to avoid this problem.

Mailbox separator can also be backslash ('\') character. Make sure you use it correctly:

1 LIST "" *
* LIST () "\\" "hello\\world"
1 OK
2 SELECT "hello\\world"

Mailbox names

Mailbox names are in modified UTF-7 format as specific by the IMAP RFC. Display and create mailboxes using UTF-7. However existing mailbox names might already be wrong, so try not to break if you see 8bit characters. You should try to show them as UTF-8 (future IMAP RFCs might move to using UTF-8), or if the name isn't valid UTF-8 show them any way you want.

When parsing the LIST replies, remember that mailbox names may also be literals. This is perfectly legal:

1 list "" %
* LIST () "/" {7}
"hello"
1 OK

Children

If server capabilities contain [http://www.ietf.org/rfc/rfc3348.txt CHILDREN] or [:Specs/ListExtended:LIST-EXTENDED], you might see \HasChildren and \HasNoChildren flags in LIST replies. It's not required however that these are listed unless you explicitly request them with LIST-EXTENDED. So if don't see either of them, you can't assume anything about its children state. Note however that \NoInferiors implies \HasNoChildren.

If you don't know the children state, there's a simple way to find out. Try to list its children to see if it returns anything:

1 LIST "" box/%

If you see any replies, it has children, otherwise it doesn't.

If you want to know children status for all root mailboxes and the children flags weren't returned for LIST "" %, you can use:

1 LIST "" %/%

If server supports LIST-EXTENDED, you can force the it to return children flags:

1 LIST () "" % RETURN (CHILDREN)

Namespaces