Таак. Здесь опишу процесс настройки доставки писем прямо в указанные папки.
1. Заводим в базе 2 дополнительные таблицы для хранения правил, там будут типы правил и сами правила. Типов пока 4 - по заголовкам from, to и subject и еще по пометке "спам" (скрипты дл создания в следующем посте). Описание таблицы юзеров (dbmail_users) не привожу, ранее писал про нее, она используется в запросе.
2. Переходим к настройке exim. Первое, что надо сделать, это сделать так, чтоб после завершения процесса проверки письма при переходе его в состояние локальной доставки сохранились значения заголовков From: To: Subject:. Для этого используем глобальные переменные типа $acl_cx (x - от 0 до 9, итого 10 переменных можно заюзать). В цепочке "acl_check_message:" запомним эти переменные (перекодируя заголовки в нормальный вид перловой функцией header_decode, описание которой есть в предыдущем посте про перл).
warn message =
set acl_c0 = ${perl{header_decode}{$rheader_from:}}
set acl_c1 = ${perl{header_decode}{$rheader_to:}}
set acl_c2 = ${perl{header_decode}{$rheader_subject:}}
set acl_c3 = $spam_score_int
Обращу внимание, что при использовании переменных с именами заголовков в конце необходимо ставить двоеточие, накололся с этим я жестоко!
Второе - переходим непосредственно к доставке письма. В транспорте локальной доставки укажем, в какую папку доставлять:
address_delivery1:
driver = appendfile
create_directory = true
directory_mode = 700
directory = /var/mail/${domain}/${local_part}/${lookup mysql{SELECT r.folder FROM rules r INNER JOIN dbmail_users u ON r.user_id = u.id INNER JOIN rules_types rt ON rt.id = r.type WHERE lower(u.userid) = lower("$local_part") AND lower(u.domen) = lower("$domain") AND ((rt.type = "from" AND "${sg {$acl_c0}{"}{""}}" LIKE CONCAT("%",r.val,"%")) OR (rt.type = "to" AND "${sg {$acl_c1}{"}{""}}" LIKE CONCAT("%",r.val,"%")) OR (rt.type = "subject" AND "${sg {$acl_c2}{"}{""}}" LIKE CONCAT("%",r.val,"%")) OR (rt.type = "spam" AND CAST("$acl_c3" AS SIGNED) >= r.val)) ORDER BY r.ord LIMIT 1}}
user = mail
group = mail
delivery_date_add
envelope_to_add
return_path_add
maildir_format = true
mode = 660
Пусть не пугает сложность запроса - ничего сложного нет, общий смысл - если подпало под какое-нить правило письмо согласно заголовкам, то запрос выберет имя папки, если нет - выберет NULL и письмо придет в INBOX.
Можно было вместо LIKE заюзать RLIKE и искать совпадение по регулярному выражению, но сделано LIKE с учетом того, что пользователи смогут через веб редактировать свои правила сами, и они же не знают что есть регулярное выражение.
Если папка не существует - она будет создана, но потом пользователю надо будет на нее подписаться.
3. Ну вот в принципе и все, остается теперь пользователям заводить свои правила в базу, для этого можно либо веб-морду написать, либо еще что... А, важный момент - в базу имя папки должно уже попадать в закодированном виде. По стандарту - это жутчайшее сочетание utf7 и utf16, функция для кодировки в посте ниже (пример мой на пхп).