Loading...

Special-Use Mailboxes

On IMAP servers, there will be mailboxes(folders) which are dedicated to very specific content, such as:

  • Sent Messages: When sending an e-mail, a copy will be stored there
  • Deleted Messages: When pressing the „Delete“ button, the marked e-mail(s) will be moved in this folder

Most often, these folders are outlined with icons in the e-mail client such as the following:

In most cases, people will access their IMAP mailboxes with multiple clients, such as Thunderbird, Microsoft Outlook, mobile phone clients etc.

It is important that these special folders are configured the same for every client. For many clients, such as Thunderbird, these folders can be configured as needed. Modern versions of Microsoft Outlook do not provide such functionality, so quite often there are IMAP-based accounts, that have multiple folders for sent e-mails, deleted e-mails etc. This way the folder structure can become quite messy.

RFC 6154 solves this problem by introducing so-called „special-use“ mailboxes (= folders). It defines specific special-use attributes, which can then be assigned to these mailboxes. The following flags are available:

   \All
        This mailbox presents all messages in the user's message store.
        Implementations MAY omit some messages, such as, perhaps, those
        in \Trash and \Junk.  When this special use is supported, it is
        almost certain to represent a virtual mailbox.

   \Archive
        This mailbox is used to archive messages.  The meaning of an
        "archival" mailbox is server-dependent; typically, it will be
        used to get messages out of the inbox, or otherwise keep them
        out of the user's way, while still making them accessible.

   \Drafts
        This mailbox is used to hold draft messages -- typically,
        messages that are being composed but have not yet been sent.  In
        some server implementations, this might be a virtual mailbox,
        containing messages from other mailboxes that are marked with
        the "\Draft" message flag.  Alternatively, this might just be
        advice that a client put drafts here.

   \Flagged
        This mailbox presents all messages marked in some way as
        "important".  When this special use is supported, it is likely
        to represent a virtual mailbox collecting messages (from other
        mailboxes) that are marked with the "\Flagged" message flag.

   \Junk
        This mailbox is where messages deemed to be junk mail are held.
        Some server implementations might put messages here
        automatically.  Alternatively, this might just be advice to a
        client-side spam filter.

   \Sent
        This mailbox is used to hold copies of messages that have been
        sent.  Some server implementations might put messages here
        automatically.  Alternatively, this might just be advice that a
        client save sent messages here.

   \Trash
        This mailbox is used to hold messages that have been deleted or
        marked for deletion.  In some server implementations, this might
        be a virtual mailbox, containing messages from other mailboxes

Mail Clients

When an e-mail client connects to an IMAP server, it first tries to list all folders with these special-use flags and tries to use these mailboxes accordingly. It is not 100% clear to me what e-mail client regard these special-use attributes correctly, however, Microsoft Outlook seems to interprete them most of the times. It may be necessary to reset the folders in case something changes. This can be done like the following:
 
outlook.exe /resetfolders 
outlook.exe /resetfoldernames
Or with an example of the full path
 
"C:\Program Files (x86)\Microsoft Office\root\Office16\outlook.exe" /resetfolders 
"C:\Program Files (x86)\Microsoft Office\root\Office16\outlook.exe" /resetfoldernames

IMAP commands

It may be helpful to know the IMAP commands in order to check or manually set these special-use attributes. (This applies to the IMAP-server „cyrus, version 3 but should be applicable to other IMAP-servers as well.)
 
For listing mailboxes and special-use attributes, the following command can be used:
 
list "" "%" return (special-use)
The result will be something like this:
 
INBOX : \HasNoChildren 
Arbeit : \HasChildren
Drafts : \HasNoChildren, \Drafts
Sent : \HasChildren, \Sent

Setting the special-use flags can be done with the setmetadata command:

setmetadata Spam (/private/specialuse "\Junk")
It is worth noting that before modifying a special-use attribute it has to be deleted first like this:
 
setmetadata Spam (/private/specialuse NIL)
A full IMAP session that connects to a server via unencrypted port 143, lists and sets a special-use attribute is given as an example below:
 
telnet  143
Trying ...
Connected to
Escape character is '^]'.
* OK [CAPABILITY ...] Cyrus
server ready
10 login
10 OK [CAPABILITY IMAP4rev1 ...] User logged in SESSIONID=
11 list "" "%" return (special-use)
* LIST (\HasNoChildren) "/" INBOX
...
* LIST (\HasChildren \Sent) "/" Sent
* LIST (\HasNoChildren \Junk) "/" Spam
* LIST (\HasNoChildren) "/" Templates
* LIST (\HasNoChildren \Trash) "/" Trash
11 OK Completed (0.003 secs 101 calls)
12 setmetadata Trash (/private/specialuse NIL)
12 OK Completed
13 setmetadata Trash (/private/specialuse "\Trash")
13 OK Completed
14 logout
* BYE LOGOUT received
14 OK Completed
Connection closed by foreign host.
 

Python Script

As this is quite tedious, it may be helpful to have a script that at least lists all special-use mailboxes. A simple Python script for that is shown here:
 

#!/usr/bin/env python3

import imaplib
import ssl
import getpass
import argparse
from collections import defaultdict

def main():
# Parse command-line arguments
parser = argparse.ArgumentParser(description='List IMAP mailboxes with special-use flags.')
parser.add_argument('-s', '--hostname', type=str, help='IMAP server hostname')
parser.add_argument('-u', '--username', type=str, help='Username for login')
parser.add_argument('-p', '--password', type=str, help='Password for login')
args = parser.parse_args()

# Prompt for missing parameters
if not args.hostname:
args.hostname = input("Enter the IMAP server address: ")
if not args.username:
args.username = input("Enter your username: ")
if not args.password:
args.password = getpass.getpass("Enter your password: ")

# Special-use flags
special_use_flags = {
'\\All': 'All',
'\\Archive': 'Archive',
'\\Drafts': 'Drafts',
'\\Flagged': 'Flagged',
'\\Junk': 'Junk',
'\\Sent': 'Sent',
'\\Trash': 'Trash'
}

# Connect to the server
context = ssl.create_default_context()
with imaplib.IMAP4_SSL(args.hostname, port=993, ssl_context=context) as mail:
try:
# Login to the server
mail.login(args.username, args.password)

# Send the LIST command with RETURN (SPECIAL-USE)
command = '0001 LIST "" "%" RETURN (SPECIAL-USE)\r\n'
mail.send(command.encode())

# Retrieve and print the response
special_use_mailboxes = defaultdict(list)
while True:
response = mail.readline().decode().strip()
if response.startswith('0001 OK'):
break
elif 'SPECIAL-USE' in response:
continue
elif '\\' in response:
parts = response.split(') "/" ')
flags = parts[0].split('(')[1]
mailbox = parts[1]
for flag in flags.split():
if flag in special_use_flags:
special_use_mailboxes[special_use_flags[flag]].append(mailbox)

# Print the formatted output
print("Mailboxes with special-use flags:")
for flag, mailboxes in special_use_mailboxes.items():
print(f"{flag}: Mailboxes: {', '.join(mailboxes)}")

except imaplib.IMAP4.error as e:
print(f"Failed to connect or log in: {e}")

if __name__ == '__main__':
main()

The script in action looks like the following:
 
 ./imap-specialuse.py -s  -u   -p  
Mailboxes with special-use flags:
Drafts: Mailboxes: Drafts
Sent: Mailboxes: Sent
Junk: Mailboxes: Spam
Trash: Mailboxes: Trash
Top