The maildirmake command creates maildirs, and maildir folders. This documentation describes the maildirmake command from the Courier mail server, which creates an extended form of maildirs that implements additional extensions beyond the basic maildir properties that were first implemented in the Qmail mail server.
A "Maildir" is a directory that holds mail messages, one message per file. But not just any directory will do - a Maildir must have a specific structure that enables mail access without requiring any kind of locking, and have specific access permissions. The maildirmake command is a convenient way to create a new Maildir, or a new folder within an existing Maildir, with the correct permission and structure.
create a "sharable" maildir. A sharable maildir has slightly different permissions which allows creation of publicly-shared folders.
install a quota on the maildir. See "Maildir Quotas", below.
do not create a maildir, but create a folder in an existing maildir.
create a publicly accessible folder in an existing sharable maildir. First, use the -S option to create a sharable maildir. Then, run maildirmake again with the -s option to create publicly accessible folders. mode is a comma-separated list of the following keywords: read - readonly folder, only you can write messages to this folder; write - anyone can read and write messages to this folder; group - only allow members of your own system group to access messages in this folder (instead of everyone).
create or delete the directories and links needed to access shared folders. See below for more information.
This maildirmake command supports enhanced maildirs that contain folders.
By itself, maildirmake makes a new subdirectory maildir, and creates all the necessary structures. The -f option creates a new "folder" within an existing maildir. maildir must already exist, and the maildirmake command will create a new folder in the maildir.
Folders are simply subdirectories inside the main maildir whose names start with a period, and which are themselves maildirs. For example, the command "maildirmake -f Drafts mail/Maildir" creates mail/Maildir/.Drafts, that has the usual tmp, new and cur. You MUST use the -f option, instead of specifying mail/Maildir/.Drafts directly, in order to correctly initialize certain enhanced maildir features.
Folders cannot be created directly within other folders. Running maildirmake -f Urgent mail/Maildir/.Drafts will not work. Instead, the period character is designated as a hierarchy separator, run maildirmake -f Drafts.Urgent mail/Maildir instead. This creates mail/Maildir/.Drafts.Urgent, and all mail software that supports enhanced maildirs will interpret it as a subfolder Urgent of the Drafts folder.
This is another extension to the Maildir format that allows folders to be shared between multiple clients. First, you need to create a collection of sharable folders, as a separate maildir:
Then, create individuals folders that will be accessed in shared mode:
In this example, the "Weekly" folder is created, with read/write access to everyone. Multiple folders can be created in the same maildir, with different access permissions. Everyone can create a sharable maildir. The access privileges for individual folders are set by the -s option, and are implemented using traditional filesystem permissions.
Use the --add and --del options to add a sharable maildir to an existing maildir. Client software that implements this extension will now know where to find sharable folders:
$HOME/Maildir is your main maildir. The argument to -add is nick=path. nick is a nickname for this collection of sharable folders, and path is the location of the sharable maildir. All folders in the sharable maildir that you have access to -- such as "Weekly", in this case, will now be accessible. Multiple sharable maildirs can be added, by giving each one a unique nick.
The --del option "disconnects" the sharable maildir from the main maildir.
Normally -add command must be run for every maildir which needs to access the sharable maildir. Alternatively the file /usr/local/etc/maildirshared can be created, to specify a default set of sharable maildirs. Each line in this file takes the following format:
nick is a short nickname for the sharable maildir, <tab> is a single tab character, path is the pathname to the sharable maildir.
You may have read or write access to a shared folder. If you have write access, you can add messages to the shared folder. You can also delete messages that you've added.
Anyone can create a sharable maildir, so if the sharable maildir is actually created by you, can can delete any message, not just your own.
The rest of this manual page describes the technical implementation of Maildirs. The first implementation and definition of Maildirs was in Dan Bernstein's Qmail mail server, and it described a single, flat, mail repository. The Courier mail server adds additional features such as folders and voluntary mail quotas. This document describes the enhanced Maildir implementation without identifying the specific enhancements to the original Maildir implementation. See http://www.qmail.org/man/man5/maildir.html for the original specifications of Maildirs.
Maildirs offer several improvements over traditional mailbox files. Unlike mailbox files, no locking is necessary in order to deliver new messages to maildirs, or to read mail in maildirs. Multiple agents can deliver new mail to maildirs, in parallel, and read mail from maildirs. Locking is often problematic with certain network file system. Maildirs require no locking, and can be implemented on top of almost any file system.
A maildir is an ordinary subdirectory, with group and world access permissions revoked, of course. A maildir contains three subdirectories: tmp, new, and cur. Folders are additional subdirectories whose names begin with a period: such as .Drafts or .Sent. Each folder itself contains the same three subdirectories, tmp, new, and cur, and can be thought of as a maildir in of itself, except that it itself cannot contain nested folder subdirectories, as explained above.
A folder subdirectory also contains an extra, zero-length file named maildirfolder, whose purpose is to simply inform any mail delivery agent that it really is delivering to a folder, and that the mail delivery agent should look in the parent directory for any required housekeeping information. Software that uses maildirs may also create additional files besides the tmp, new, and cur subdirectories -- in the main maildir or a folder "submaildir" -- for its own use.
E-mail messages are stored in separate, individual files as defined below, one E-mail message per file. The tmp subdirectory temporarily stores E-mail messages that are in the process of being delivered to this maildir. tmp may also store other kinds of temporary files, as long as they follow the same filename naming convention for creating new files in tmp. The new subdirectory stores messages that have been delivered to this maildir, but have not yet been seen by any mail application. The cur subdirectory stores messages that have already been seen by mail applications.
The following process is used to deliver mail to a maildir:
A new unique filename is created using one of two possible forms: "time.pid.host", or "time.pid_unique.host". "time" is the current system time, in seconds. "pid" is the process number of the process that is delivering this message to the maildir. "host" is the name of the machine where the mail is being delivered. In the event that the same process will create multiple messages, it should append a unique suffix to the process id, preferrably an underscore, followed by an increasing counter. This applies whether messages created by a process are all in the same, or different, maildirs. This protocol allows multiple processes running on multiple machines on the same network to simultaneously create new messages without stomping on each other.
The filename created in the previous step is checked for existence by executing the stat(2) system call, against the tmp subdirectory. If the result of the stat(2) system call is ANYTHING OTHER than the system error ENOENT, the process must sleep for two seconds, then go back and create a new unique filename. This is an extra step to insure that each new message has a completely unique filename.
Other applications that wish to use tmp for temporary storage should observe the same protocol (but see READING MAIL FROM MAILDIRS below, because old files in tmp will be eventually deleted).
If the stat(2) system call returned ENOENT, the process may procede to create the file in the tmp subdirectory, and save the entire message in the new file. The message saved MUST NOT have the traditional "From_" line that is used to separate individual messages in the traditional mailbox files. The message also MUST NOT have any "From_" lines in the contents of the message prefixed by the ">" character, as messages in traditional mailbox files are.
Saving the message means to reliably save it in a file. The number of bytes returned by the write(2) system call must be checked, in order to make sure that the complete message has been written out.
After the message is saved, the file is closed and is then immediately moved/renamed into the new subdirectory. The name of the file should be the same name it had in the tmp subdirectory.
It is HIGHLY RECOMMENDED that software that creates messages in maildirs should also append the suffix ",S=nnn" to the name of the file when it is moved into the new subdirectory, where "nnn" represents the size of the message, in bytes. This optimizes the voluntary maildir quota enhancement, as it permits the size of all the mail stored in the maildir to be added up without issuing the stat(2) system call for each individual message (which can be quite a performance drain with certain network filesystems).
Applications that read mail from maildirs should do it in the following order:
When opening a maildir or a maildir folder, read the tmp subdirectory and delete anything in there that's at least 36 hours old.
Look for new messages in the new subdirectory. For each new message found, new/filename, rename it as cur/filename:2,info. Here, info represents the state of the message, and it consists of zero or more boolean flags chosen from the following: D - this is a 'draft' message, R - this message has been replied to, S - this message has been viewed (seen), T - this message has been marked to be deleted (trashed), but is not yet removed (messages are removed from maildirs simply by deleting their file), F - this message has been marked by the user, for some purpose. These flags must be stored in alphabetic order. New messages contain only the :2, suffix, with no flags, indicating that the messages haven't been seen, replied, marked, or deleted.
Maildirs may have maximum size quotas defined, but these quotas are purely voluntary. If you need to implement mandatory quotas, you should use any quota facilities provided by the underlying filesystem that is used to store the maildirs. The maildir quota enhancement is designed to be used in certain situations where filesystem-based quotas cannot be used for some reason. The implementation is designed to avoid the use of any locking. As such, at certain times the calculated quota may be imprecise, and certain anomalous situations may result in the maildir actually going over the stated quota. One such situation would be when applications create messages without updating the quota estimate for the maildir. Eventually it will be precisely recalculated, but wherever possible new messages should be created in compliance with the voluntary quota protocol.
The voluntary quota protocol involves some additional procedures that must be followed when creating or deleting messages within a given maildir or its subfolders. The deliverquota(8) command is a tiny application that delivers a single message to a maildir using the voluntary quota protocol, and hopefully it can be used as a measure of last resort. Alternatively, applications can use the libmaildir.a library to handle all the low-level dirty details for them. The voluntary quota enhancement is described in the maildirquota(7).
This is a voluntary mechanism for enforcing "loose" quotas on the maximum sizes of maildirs. This mechanism is enforced in software, and not by the operating system. Therefore it is only effective as long as the maildirs themselves are not directly accessible by their users, since this mechanism is trivially disabled.
If possible, operating system-enforced quotas are preferrable. Where operating system quota enforcement is not available, or not possible, this voluntary quota enforcement mechanism might be an acceptable compromise. Since it's enforced in software, all software that modifies or accesses the maildirs is required to voluntary obey and enforce a quota. The voluntary quota implementation is flexible enough to allow non quota-aware applications to also access the maildirs, without any drastic consequences. There will be some non-drastic consequences, though. Of course, non quota-aware applications will not enforce any defined quotas. Furthermore, this voluntary maildir quota mechanism works by estimating the current size of the maildir, with periodic exact recalculation. Obviously non quota-aware maildir applications will not update the maildir size estimation, so the estimate will be thrown off for some period of time, until the next recalculation.
This voluntary quota mechanism is designed to be a reasonable compromise between effectiveness, and performance. The entire purpose of using maildir-based mail storage is to avoid any kind of locking, and to permit parallel access to mail by multiple applications. In order to compute the exact size of a maildir, the maildir must be locked somehow to prevent any modifications while its contents are added up. Obviously something like that defeats the original purpose of using maildirs, therefore the voluntary quota mechanism does not use locking, and that's why the current recorded maildir size is always considered to be an estimate. Regular size recalculations will compensate for any occasional race conditions that result in the estimate to be thrown off.
A quota for an existing maildir is installed by running maildirmake with the -q option, and naming an existing maildir. The -q option takes a parameter, quota, which is a comma-separated list of quota specifications. A quota specification consists of a number followed by either 'S', indicating the maximum message size in bytes, or 'C', maximum number of messages. For example:
This sets the quota to 5,000,000 bytes or 1000 messages, whichever comes first.
This sets the quota to 1,000,000 bytes, without limiting the number of messages.
A quota of an existing maildir can be changed by rerunning the maildirmake command with a new -q option. To delete a quota entirely, delete the Maildir/maildirsize file.