D. J. Bernstein
Internet mail<br>Using maildir format
Why should I use maildir?
Two words: no locks .<br>An MUA can read and delete messages while new mail is being delivered:<br>each message is stored in a separate file with a unique name,<br>so it isn't affected by operations on other messages.<br>An MUA doesn't have to worry about partially delivered mail:<br>each message is safely written to disk in the tmp subdirectory<br>before it is moved to new .<br>The maildir format is reliable even over NFS.<br>How are unique names created?
Unless you're writing messages to a maildir,<br>the format of a unique name is none of your business.<br>A unique name can be anything<br>that doesn't contain a colon (or slash)<br>and doesn't start with a dot.<br>Do not try to extract information from unique names.
Okay, so you're writing messages.<br>A unique name has three pieces, separated by dots.<br>On the left is the result of time() or the second counter from gettimeofday().<br>On the right is the result of gethostname().<br>(To deal with invalid host names,<br>replace / with \057 and : with \072.)<br>In the middle is a delivery identifier, discussed below.
As the terminology suggests,<br>every delivery to this maildir must have its own unique name .<br>When a maildir is shared through NFS,<br>every machine that delivers to the maildir must have its own hostname.<br>Within one machine,<br>every delivery within the same second<br>must have a different delivery identifier.
Modern delivery identifiers are created by concatenating<br>enough of the following strings to guarantee uniqueness:
#n,<br>where n is (in hexadecimal) the output of<br>the operating system's unix_sequencenumber() system call,<br>which returns a number that increases by 1 every time it is called,<br>starting from 0 after reboot.<br>Xn,<br>where n is (in hexadecimal) the output of<br>the operating system's unix_bootnumber() system call,<br>which reports the number of times that the system has been booted.<br>Together with #, this guarantees uniqueness;<br>unfortunately, most operating systems don't support<br>unix_sequencenumber() and unix_bootnumber.<br>Rn,<br>where n is (in hexadecimal) the output of<br>the operating system's unix_cryptorandomnumber() system call,<br>or an equivalent source such as /dev/urandom.<br>Unfortunately,<br>some operating systems don't include cryptographic random number generators.<br>In,<br>where n is (in hexadecimal) the UNIX inode number of this file.<br>Unfortunately, inode numbers aren't always available through NFS.<br>Vn,<br>where n is (in hexadecimal) the UNIX device number of this file.<br>Unfortunately, device numbers aren't always available through NFS.<br>(Device numbers are also not helpful with the standard UNIX filesystem:<br>a maildir has to be within a single UNIX device<br>for link() and rename() to work.)<br>Mn,<br>where n is (in decimal) the microsecond counter<br>from the same gettimeofday() used for the left part of the unique name.<br>Pn,<br>where n is (in decimal) the process ID.<br>Qn,<br>where n is (in decimal) the number of deliveries made by this process.
Old-fashioned delivery identifiers use the following formats:
n, where n is the process ID,<br>and where this process has been forked to make one delivery.<br>Unfortunately,<br>some foolish operating systems repeat process IDs quickly,<br>breaking the standard time+pid combination.<br>n_m, where n is the process ID<br>and m is the number of deliveries made by this process.
What can I put in info?
When you move a file from new to cur ,<br>you have to change its name from uniq to uniq:info.<br>Make sure to preserve the uniq string,<br>so that separate messages can't bump into each other.
info is morally equivalent to the Status field used by mbox readers.<br>It'd be useful to have MUAs agree on the meaning of info,<br>so I'm keeping a list of info semantics.<br>Here it is.
info starting with "1,": Experimental semantics.
info starting with "2,":<br>Each character after the comma is an independent flag.
Flag "P" (passed): the user has resent/forwarded/bounced this message<br>to someone else.<br>Flag "R" (replied): the user has replied to this message.<br>Flag "S" (seen): the user has viewed this message, though perhaps<br>he didn't read all the way through it.<br>Flag "T" (trashed): the user has moved this message to the trash;<br>the trash will be emptied by a later user action.<br>Flag "D" (draft): the user considers this message a draft;<br>toggled at user discretion.<br>Flag "F" (flagged): user-defined flag; toggled at user discretion.
New flags may be defined later.<br>Flags must be stored in ASCII order: e.g., "2,FRS".<br>Can a maildir contain more than tmp, new, cur?
Yes:
.qmail: used to do direct deliveries with qmail-local.<br>bulletintime: empty file, used by system-wide bulletin programs.<br>bulletinlock: empty file, used by system-wide bulletin programs.<br>seriallock: empty file, used to serialize AutoTURN.