Maildir

Формат электронной почты

Формат электронной почты Maildir — это распространенный способ хранения сообщений электронной почты в файловой системе , а не в базе данных. Каждому сообщению назначается файл с уникальным именем, а каждая почтовая папка — это каталог файловой системы, содержащий эти файлы. Maildir был разработан Дэниелом Дж. Бернстайном около 1995 года с главной целью — исключить необходимость в программном коде для обработки блокировки и разблокировки файлов с помощью локальной файловой системы. [1] Дизайн Maildir отражает тот факт, что единственными операциями, допустимыми для сообщения электронной почты, являются его создание, удаление или изменение его статуса каким-либо образом.

Внутренняя структура

Технические характеристики

Каталог Maildir (часто называемый Maildir) обычно имеет три подкаталога с именами tmp, newи cur. [2]

  • Подкаталог tmpвременно хранит сообщения электронной почты, которые находятся в процессе доставки. Этот подкаталог может также хранить другие виды временных файлов.
  • В newподкаталоге хранятся сообщения, которые были доставлены, но еще не просмотрены ни одним почтовым приложением.
  • В curподкаталоге хранятся сообщения, которые уже были просмотрены почтовыми приложениями. [3]

Maildir++

Сэм Варшавчик, автор Courier Mail Server и другого программного обеспечения, определил расширение Maildir++ [3] [4] для формата Maildir для поддержки подпапок и почтовых квот. Каталоги Maildir++ содержат подкаталоги с именами, начинающимися с '.' (точка), которые также являются папками Maildir++. Расширение соответствует исходной спецификации Maildir, которая допускает подкаталоги в дополнение к tmp , new и cur .

Техническая эксплуатация

Агент доставки почты — это программа , которая доставляет сообщение электронной почты в Maildir. Агент доставки почты создает новый файл с уникальным именем в tmpкаталоге. [5] [6] [3] Во время его изобретения гарантировать уникальные имена файлов было сложно. Первоначальный алгоритм qmail [1] для уникальных имен был следующим:

  1. прочитать текущее время Unix
  2. прочитать текущий идентификатор процесса (PID)
  3. прочитать текущее имя хоста
  4. объединить три приведенных выше значения в строку, разделенную символом точки ; это новое имя файла
  5. если stat()сообщает, что имя файла существует, то подождите две секунды
  6. перейти к предыдущему шагу, пока имя файла не будет существовать
  7. создайте файл с уникальным именем и запишите содержимое сообщения в новый файл

К 2000 году автор qmail рекомендовал в обновленной спецификации [5] добавлять значение счетчика для каждого процесса к PID, значение которого должно увеличиваться после каждой доставки. Рекомендация по ограничению скорости «подождать две секунды» была отменена.

К 2003 году рекомендации были дополнительно изменены, чтобы вместо PID и счетчика средняя часть имени файла создавалась путем «объединения достаточного количества следующих строк для гарантии уникальности» даже в случае нескольких одновременных доставок в один и тот же почтовый каталог от одного или нескольких процессов: [7]

  • # n , где n — это (в шестнадцатеричном формате) вывод unix_sequencenumber()системного вызова операционной системы, который возвращает число, увеличивающееся на 1 при каждом вызове, начиная с 0 после перезагрузки.
  • X n , где n — это (в шестнадцатеричном формате) вывод unix_bootnumber()системного вызова операционной системы, который сообщает количество загрузок системы. Вместе с # это гарантирует уникальность; к сожалению, большинство операционных систем не поддерживают unix_sequencenumber()и unix_bootnumber().
  • R n , где n — это (в шестнадцатеричном формате) вывод unix_cryptorandomnumber()системного вызова операционной системы или эквивалентный источник, например /dev/urandom. К сожалению, некоторые операционные системы не включают криптографические генераторы случайных чисел.
  • В n , где n — это (в шестнадцатеричном формате) номер инода UNIX этого файла. К сожалению, номера инодов не всегда доступны через NFS .
  • V n , где n — это (в шестнадцатеричном формате) номер устройства UNIX этого файла. К сожалению, номера устройств не всегда доступны через NFS. (Номера устройств также бесполезны в стандартной файловой системе UNIX: maildir должен находиться в пределах одного устройства UNIX для link()и rename()для работы.)
  • M n , где n — (в десятичной системе) счетчик микросекунд, gettimeofday()используемый в левой части уникального имени.
  • P n , где n — идентификатор процесса (в десятичной системе счисления).
  • Q n , где n — (в десятичной дроби) количество доставок, выполненных данным процессом.

Этот алгоритм 2003 года подвергся критике [8] в 2006 году как излишне сложный со стороны Тимо Сирайнена , создателя Dovecot .

По состоянию на ноябрь 2023 года автор qmail Дэниел Бернстайн не внес никаких дальнейших изменений в рекомендации по генерации имен файлов 2003 года. [9] В современных системах POSIX временные файлы можно безопасно создавать с помощью mkstempфункции библиотеки C.

Процесс доставки сохраняет сообщение в maildir путем создания и записи в , а затем перемещения этого файла в . Перемещение может быть выполнено с помощью , что является атомарным во многих системах. [10] В качестве альтернативы это можно сделать путем жесткой привязки файла к , а затем удаления ссылки на файл из . Любой оставшийся файл в конечном итоге будет удален. Эта последовательность гарантирует, что программа, читающая maildir, не увидит частично записанное сообщение. Может быть несколько программ, читающих maildir одновременно. Они варьируются от почтовых пользовательских агентов (MUA), которые напрямую обращаются к файловой системе сервера, через серверы протокола доступа к сообщениям в Интернете или почтового протокола, действующие от имени удаленных MUA, до таких утилит, как biff и rsync , которые могут знать или не знать о структуре maildir. Читатели никогда не должны заглядывать в .tmp/uniquefilenamenew/uniquefilenamerenamenewtmptmp

Когда осознанный процесс чтения maildir (либо сервер POP или IMAP , либо почтовый агент пользователя, действующий локально) находит сообщения в newкаталоге, он должен переместить их в cur. Это всего лишь способ уведомить пользователя «у вас есть X новых сообщений». [11] Это перемещение должно быть выполнено с использованием атомарной файловой системы rename(), поскольку альтернативный метод связывания-затем-отсоединения является неатомарным и может привести к дублированию сообщений. На этом этапе к именам файлов добавляется информационный суффикс. Он состоит из двоеточия ( для отделения уникальной части имени файла от фактической информации), «2», запятой и различных флагов . «2» указывает версию информации, которая следует за запятой. «2» — единственная официально указанная в настоящее время версия, «1» — экспериментальная версия. Спецификация определяет флаги, которые показывают, было ли сообщение прочитано, удалено и т. д.: начальная (заглавная) буква слов «Passed», «Replied», «Seen», «Trashed», «Draft» и «Flagged». [7] Приложения часто решают дополнить этот весьма ограниченный набор флагов, например, notmuch [12] предлагает синхронизацию флагов в дополнение к произвольным определяемым пользователем флагам, [13] в то время как Dovecot использует строчные буквы для соответствия 26 ключевым словам IMAP, [6] которые могут включать такие ключевые слова, как $ MDNSent или определяемые пользователем флаги.

Хотя Maildir был предназначен для использования без блокировки, на практике некоторое программное обеспечение, использующее Maildirs, также использует блокировки, например Dovecot. [14]

Проблемы совместимости файловой системы

Стандарт Maildir может быть реализован только в системах, которые принимают двоеточия в именах файлов. [15]

Системы, не допускающие двоеточия в именах файлов (включая Microsoft Windows и некоторые конфигурации Novell Storage Services ), могут использовать нестандартный альтернативный разделитель, такой как ";" или "-". Часто бывает просто исправить свободное и открытое программное обеспечение , чтобы использовать другой разделитель. [16]

Поскольку в настоящее время нет соглашения о том, какой символ должен быть этим альтернативным разделителем, могут возникнуть трудности с совместимостью между различными программами, поддерживающими Maildir, в этих системах. Однако не все программное обеспечение, связанное с Maildir, должно знать, какой символ является разделителем, поскольку не все программное обеспечение, связанное с Maildir, должно иметь возможность читать или изменять флаги сообщения («прочитано», «ответил» и т. д.); программное обеспечение, которое просто доставляет в Maildir или архивирует старые сообщения из него, основываясь только на дате, должно работать независимо от того, какой разделитель используется. Если только MUA необходимо читать или изменять флаги сообщений, и используется только один MUA, то нестандартные альтернативные разделители могут использоваться без проблем с совместимостью.

Программное обеспечение, которое напрямую поддерживает Maildir

  • Dovecot IMAP-сервер
  • Courier Mail Server SMTP и IMAP сервер, для которого был изобретен формат Maildir++
  • Sendmail Оригинальный SMTP-сервер
  • Exim SMTP-сервер
  • Postfix SMTP-сервер
  • qmail SMTP-сервер, для которого был изобретен формат Maildir
  • SMTP-сервер MeTA1
  • OpenSMTPD SMTP-сервер
  • Stalwart Mail Server, SMTP и IMAP сервер, реализованный на Rust
  • прокмейл
  • Агент по доставке Dovecot
  • почтовая рассылка
  • getmail — Maildir-совместимый агент получения и доставки почты, альтернатива Fetchmail
  • фдм
  • muchsync, синхронизация почтовых ящиков notmuch mail между любым количеством реплик
  • ОффлайнIMAP
  • isync, синхронизирует почтовые ящики, поддерживает Maildir и IMAP4
  • Attomail — минимальный MDA с поддержкой Maildir, реализованный на Haskell
  • aerc [17] (эффективный и расширяемый почтовый клиент)
  • Balsa ранее была официальным почтовым клиентом GNOME (до Evolution)
  • Cone — программа для чтения почты на основе проклятий
  • Evolution , официальный почтовый клиент GNOME
  • GNUMail
  • Гнус
  • KMail , почтовый клиент KDE
  • mailx
  • Матт
  • Notmuch [18] (быстрая, глобальная поисковая и основанная на тегах система электронной почты)
  • Сосна/Альпийская
  • Mozilla Thunderbird – экспериментальный и «отключен по умолчанию, поскольку все еще имеет много ошибок» [19]

Примечания и ссылки

  1. ^ ab Bernstein, Daniel J. (1995). "maildir(5)". Архивировано из оригинала 12.10.1997 . Получено 23.11.2018 .
  2. ^ Блум, Ричард (2001). Postfix. Sams Publishing. ISBN 978-0-672-32114-6.
  3. ^ abc Варшавчик, Сэм (2009). "maildir(5)". Архивировано из оригинала 2024-04-17 . Получено 2024-08-09 .
  4. ^ Варшавчик, Сэм (2011). "Maildir++". Архивировано из оригинала 2024-05-29 . Получено 2024-08-09 .
  5. ^ ab Bernstein., Daniel J. (c. 2000) [Впервые опубликовано в 2000 году или ранее]. "Использование формата maildir". Архивировано из оригинала 2000-09-02 . Получено 2018-11-23 .
  6. ^ ab Dovecot Wiki: формат maildir
  7. ^ ab Bernstein., Daniel J. (2003) [Самая ранняя версия этого документа была впервые опубликована в 2000 году или ранее]. "Использование формата maildir". Архивировано из оригинала 2003-04-01 . Получено 2018-11-23 .
  8. ^ Сирайнен, Тимо . "Формат почтового ящика Maildir: Доставка почты". Архивировано из оригинала 24.06.2024 . Получено 09.08.2024 . Все эти проблемы довольно бессмысленны. Только первый шаг действительно гарантирует, что письма не будут перезаписаны, остальное просто звучит хорошо. Даже если они могут время от времени обнаруживать проблему, они не дают гарантированной защиты и будут так же легко пропускать дублирующиеся имена файлов и перезаписывать существующие письма.¶ Шаг 2 бессмыслен, потому что между шагами 2 и 3 есть состояние гонки. Комбинация PID/хоста сама по себе уже должна гарантировать, что такой файл никогда не будет найден. Если это так, что-то сломалось, и проверка stat() не поможет, так как другой процесс может делать то же самое в то же время, и вы в конечном итоге пишете в тот же файл в tmp/, что приводит к повреждению почты.¶ На шаге 4 link() не сработает, если идентичный файл уже существует в Maildir, верно? Неправильно. Файл мог быть уже перемещен в каталог cur/, и поскольку к тому времени он может содержать любое количество флагов, вы больше не сможете проверить с помощью простой stat(), существует он или нет.¶ Шаг 2 был указан как полезный, если часы перешли в обратную сторону. Однако это не дает никаких фактических гарантий безопасности, так как идентичное базовое имя файла уже может существовать в cur/. Кроме того, если система была только что перезагружена, файл в tmp/, вероятно, можно было бы даже безопасно перезаписать (предполагая, что он еще не был связан с new/).¶ Так что на самом деле, все, что важно для того, чтобы письма не были перезаписаны в вашем Maildir, это шаг 1: Всегда создавайте имена файлов, которые гарантированно будут уникальными. Забудьте о 2-секундном ожидании и тому подобном, о чем говорится на странице руководства Qmail.
  9. ^ "Снимки Wayback Machine cr.yp.to/proto/maildir.html". Архив Интернета . 2023 . Получено 23.11.2023 .
  10. ^ "rename". The Open Group . 2013 . Получено 23 июля 2016 . Эта спецификация требует, чтобы действие функции было атомарным.
  11. ^ Сэм Варшавчик (25 июля 2016 г.). «Управление структурами maildir». courier-users (список рассылки) . Получено 26 июля 2016 г.
  12. ^ "Домашняя страница почтовой системы Notmuch". notmuchmail.org . Получено 22.06.2019 .
  13. ^ "документация notmuch 0.38.3". notmuch-config . Получено 2024-04-17 .
  14. ^ Сирайнен, Тимо . "Maildir Mailbox Format: Locking". Архивировано из оригинала 2024-06-24 . Получено 2024-08-09 .
  15. ^ "mailbox — Управление почтовыми ящиками в различных форматах". Документация Python . Получено 2023-06-19 .
  16. ^ Поддержка mutt maildir: обходной путь для файловых систем, которые не принимают двоеточия
  17. ^ "aerc - лучшая в мире домашняя страница почтового клиента". aerc-mail.org .
  18. ^ "Домашняя страница почтовой системы Notmuch". notmuchmail.org . Получено 22.06.2019 .
  19. ^ "Maildir в Thunderbird". mozilla.org . Получено 2020-12-06 .

Смотрите также

  • страница руководства для maildir
  • спецификации maildir
Взято с "https://en.wikipedia.org/w/index.php?title=Maildir&oldid=1247311082"