This documentation is for Dovecot v2.x, see wiki1 for v1.x documentation.
Differences between revisions 2 and 3
Revision 2 as of 2009-12-16 01:07:25
Size: 7721
Editor: TimoSirainen
Comment:
Revision 3 as of 2021-09-24 15:11:47
Size: 72
Editor: TimoSirainen
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
= Mailbox List =

{{{src/lib-storage/mailbox-list.h}}} and {{{mailbox-list-private.h}}} describes mailbox list. The purpose of mailbox list is to manage mailbox storage name <-> physical directory path mapping. Its most important functions are:
 * listing existing mailboxes,
 * creating directories for new mailboxes (but not the mailboxes themselves, that's storage's job),
 * deleting mailboxes,
 * renaming mailboxes and
 * managing mailbox subscriptions.

Mailbox list code also internally creates and updates mailbox changelog (in {{{dovecot.mailbox.log}}} file), which keeps track of mailbox deletions, renames and subscription changes. This is primarily useful for dsync utility.

Mailbox list is configured by [[MailLocation|mail_location]] setting, which fills {{{struct mailbox_list_settings}}}:
 * root_dir: The root mail directory (e.g. with {{{mail_location=maildir:~/Maildir}}} it would be the {{{~/Maildir}}}).
 * index_dir: Directory under which index files are written to. Empty string means in-memory indexes. Defaults to root_dir.
 * control_dir: Directory under which control files are written to. Control files are files that contain some important metadata information about mailbox so (unlike index files) they should never be deleted. For example subscriptions file is a control file. Defaults to root_dir.
 * alt_dir: This is currently [[MailboxFormat/dbox|dbox]]-specific setting.
 * inbox_path: Path to INBOX mailbox. This exists mainly because with mbox format INBOX is often in a different location than other mailboxes.
 * subscription_fname: Filename used by subscriptions file.
 * dir_guid_fname: Filename used to store directories' (not mailboxes') global UIDs. Directory GUIDs are mainly useful for dsync.
 * maildir_name: Directory name under which the actual mailboxes are stored in, such as dbox-Mails/ with dbox. See the .h file for more detailed description.
 * mailbox_dir_name: If non-empty, store all mailboxes under root_dir/mailbox_dir_name/.

== Listing mailboxes ==

First the list operation is initialized with one of the init functions:

 * {{{mailbox_list_iter_init()}}} lists mailboxes that match the given pattern.
 * {{{mailbox_list_iter_init_multiple()}}} lists mailboxes that match any of the given patterns list.
 * {{{mailbox_list_iter_init_namespaces()}}} lists matching mailboxes from all namespaces.
  * {{{MAILBOX_LIST_ITER_SKIP_ALIASES}}} flag skips namespaces that have {{{alias_for}}} set. You usually want to set this flag to avoid processing the same mailbox multiple times.

The patterns are IMAP-style patterns with '%' and '*' wildcards as described by RFC 3501: '%' matches only up to next hierarchy separator, while '*' matches the rest of the string.

These flags control what mailboxes are returned:
 * {{{MAILBOX_LIST_ITER_NO_AUTO_INBOX}}} doesn't list INBOX unless it physically exists. Normally INBOX is listed, because INBOX doesn't need to be (and cannot be) explicitly created. It can always be opened and messages can be saved to it, it's just automatically created when it doesn't exist.
 * {{{MAILBOX_LIST_ITER_SELECT_SUBSCRIBED}}} lists only subscribed mailboxes.
 * {{{MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH}}} is currently only useful when combined with {{{_SELECT_SUBSCRIBED}}} flag. Then it adds {{{MAILBOX_CHILD_SUBSCRIBED}}} flags for mailboxes whose children are subscribed. It also lists mailboxes that aren't themselves subscribed, but have children that do.

These flags control what is returned for matching mailboxes:
 * {{{MAILBOX_LIST_ITER_RETURN_NO_FLAGS}}} can be set when you don't care about mailbox flags. They're then set only if it can be done without any additional disk I/O.
 * {{{MAILBOX_LIST_ITER_RETURN_SUBSCRIBED}}} returns mailbox's subscription state.
 * {{{MAILBOX_LIST_ITER_RETURN_CHILDREN}}} sets "has child mailboxes" or "doesn't have child mailboxes" flag.

Other flags:
 * {{{MAILBOX_LIST_ITER_RAW_LIST}}} should usually be avoided. It ignores ACLs and just returns everything.
 * {{{MAILBOX_LIST_ITER_VIRTUAL_NAMES}}} enables listing to use virtual names instead of storage names in patterns and returned mailbox names.

Once listing is initialized, {{{mailbox_list_iter_next()}}} can be called until it returns NULL. The returned mailbox_info struct contains:
 * {{{name}}}: Mailbox's name, either virtual or storage name depending on {{{_VIRTUAL_NAMES}}} flag.
 * {{{ns}}}: Mailbox's namespace. This is useful only when mailboxes are listed using {{{mailbox_list_iter_init_namespaces()}}}.
 * {{{flags}}}: Mailbox flags:
  * {{{MAILBOX_NOSELECT}}}: Mailbox exists, but can't be selected. It's possible that it can be created and then it becomes selectable. For example with mbox and FS layout the directories aren't selectable mailboxes.
  * {{{MAILBOX_NONEXISTENT}}}: Mailbox doesn't exist. It's listed only because it has child mailboxes that do exist but don't match the pattern.
   * Example: "foo/bar" exists, but "foo" doesn't. "%", "foo" or "*o" pattern would list "foo", because it matches the pattern but its child doesn't. Then again "*", "*bar" or "%/%" wouldn't list "foo", because "foo/bar" matches the pattern (and is also listed). Something like "*asd*" wouldn't match either "foo" or "foo/bar" so neither is returned.
  * {{{MAILBOX_CHILDREN}}} and {{{MAILBOX_NOCHILDREN}}}: Mailbox has or doesn't have children. If neither of these flags are set, it's not known if mailbox has children.
  * {{{MAILBOX_NOINFERIORS}}}: Mailbox doesn't have children and none can ever be created. For example with mbox and FS layout the mailboxes have this flag set, because files can't be created under files.
  * {{{MAILBOX_MARKED}}} and {{{MAILBOX_UNMARKED}}}: Mailbox has or doesn't have messages with \Recent flags. If neither is set, the state is unknown. Because this check is done in a very cheap way, having {{{MAILBOX_MARKED}}} doesn't always mean that there are \Recent flags. However, if {{{MAILBOX_UNMARKED}}} is returned it is guaranteed to be correct. (False positives are ok, false negatives are not ok.)
  * {{{MAILBOX_SUBSCRIBED}}}: Mailbox is subscribed.
  * {{{MAILBOX_CHILD_SUBSCRIBED}}}: Mailbox has a child that is subscribed (and {{{_SELECT_RECURSIVEMATCH}}} flag was set).

Finally the listing is deinitalized with {{{mailbox_list_iter_deinit()}}}. If it returns -1, it means that some mailboxes perhaps weren't listed due to some internal error.

If you wish to get mailbox_info flags only for a single mailbox, you can use {{{mailbox_list_mailbox()}}}.

== Directory permissions ==

{{{mailbox_list_get_permissions()}}} and {{{mailbox_list_get_dir_permissions()}}} can be used to get wanted permissions for newly created files and directories.
 * For global files, give NULL as the mailbox name. The permissions are then based on the root_dir. If root_dir doesn't exist, it returns 0700/0600 mode.
 * For per-mailbox files, give the mailbox name. The permissions are then based on the mailbox's directory.

The returned permissions are:
 * mode: Creation mode, like 0600.
 * gid: Group that should be set, unless it's {{{(gid_t)-1}}}. There are 3 reasons why it could be that:
  * directory has g+s bit set, so the wanted group is set automatically
  * group is the same as process's effective GID, so it gets set automatically
  * mode's group permissions are the same as world permissions, so group doesn't matter.
 * gid_origin: This string points to the directory where the group (and permissions in general) was based on, or "defaults" for internal defaults.

If changing the group fails with EPERM, {{{eperm_error_get_chgrp()}}} can be used to log a nice and understandable error message.
Moved to https://doc.dovecot.org/developer_manual/design/mailbox_list/

None: Design/Storage/MailboxList (last edited 2021-09-24 15:11:47 by TimoSirainen)