## Утилита тоссинга входящей почты POP3RULES.

### Общие положения.

Утилита предназначена для совместной работы с сервером почты Eserv. Ее назначение - тоссинг входящей почты в зависимости от ряда критериев, реализация автоответчика. Имеется возможность сохранения аттачментов, запуска внешних приложений в случае возникновении определенных условий в процессе тоссинга. Утилиту можно успешно применять в малых и средних локальных сетях в случае, когда входящая почта приходит на один почтовый адрес, несколько почтовых адресов либо почтовый домен и требуется пересылка внутри локальной сети.

Утилита написана на языке Форт, что вносит некоторые особенности в построение фраз и логических выражений.

Правила тоссинга записываются в файле pop3toss.rules в виде простого текста в кодировке windows-1251, который находится в каталоге agents EServ'a.

Все ключевые слова, имена функций и макропеременных должны записываться с учетом регистра и в том виде, в котором они представлены в настоящем описании.

### Строковые константы.

Запись всех строковых констант, которые имеют место в правилах тоссинга, подчиняется следующим соглашениям:

- константа может содержать произвольную последовательность русских и английских букв, цифр, символов (кодировка windows-1251);
- строковые константы, содержащие пробелы, записываются в двойных кавычках ("иванов иван"), для не содержащих пробелов допускается запись без кавычек (sidorov);
- строка может содержать символы ", при этом она заключается в угловые скобки (<"москвич">).

### Правила тоссинга.

Схема тоссинга записывается в виде групп правил и сопоставленных им действий. Каждая группа правил выглядит следующим образом:

    :- rule1 :action action1 ;
    :- rule2 :action action2 ;
    ...
    :- ruleN :action actionN ;
    ==> address1 [address2 addressM]
        :action actionN+1 ;

где rule1, rule2, ruleN - правила, action1, action2, actionN - действия, сопоставленные соответствующим правилам, actionN+1 - действие, сопоставленное группе правил. В квадратных скобках указаны то, что можно за ненадобностью опустить.

Каждое правило записывается с новой строки и открывается фразой ":-". Заканчивается правило символом ; (точка с запятой). Явное указание ; требуется только в отдельных случаях. Если для описанного правила не требуется выполнения специфического действия, конструкция :action опускается:

    :- rule1
    :- rule2
    ...
    :- ruleN
    ==> address1

Каждая группа правил оканчивается конструкцией ==> address. Эта конструкция указывает, что в случае срабатывания любого правила из группы, подлежащее разбору письмо направляется на указанный локальный почтовый адрес (адреса, разделенные пробелом).

Действие actionN+1, записанное после конструкции ==> address, выполнится также в случае срабатывания любого правила из группы и может быть опущено. Данная запись единственная, которая требует явного указания окончания правила (;).

### Конструкция правила.

Каждое правило представляет собой набор условий, возвращающих значение true или false. Условие строится на базе одной из пяти конструкций, возвращающих логическое значение:

from~ð string | поле From проверяется на предмет вхождения строки string
to~ð string | поля To, Cc, Received, X-Deliver-To проверяются на предмет вхождения строки string
subj~ð string | поле Subject проверяется на предмет вхождения строки string
body~ð string* | тело письма проверяется на предмет вхождения строки string
field: ð "fieldname"ð S"ð string"ð ~match ** | произвольное поле fieldname проверяется на предмет вхождения строки string

Замечания:

ð - символ пробела

* Если тело письма представлено text/plain, поиск строки string производится в декодированном тексте. Если тело письма представлено text/html, поиск строки string производится в теле "как оно есть".

** Обратить внимание на наличие пробелов в указанных позициях.

Утилита не чувствительна к регистру полей string, т.е. MyName = myname. В записи данных полей допускается использование масок * и ?, такие строки должны быть обязательно заключены в кавычки ("привет*вася").

Пример:

    :- from~ friend@of.mine
    ==> me@local

Условия в правиле можно комбинировать при помощи логических операторов AND, OR, 0= (not). При этом следует иметь ввиду, что в Форте применяется постфиксная форма записи выражений, т.е. выражение condition1 and condition2 будет выглядеть следующим образом: condition1 condition2 AND.

Пример:

    :- from~ вася to~ сергей AND subj~ "настройка тоссера" OR
    ==> serge@local

Все правила в группе неявно объединены операторами OR. Отсюда следует, что записи

    :- from~ myfriend
    :- to~ me
    и
    :- from~ myfriend to~ me OR

идентичны.

### Конструкция действия

Общий вид конструкции действия: :actionð forth_programð ; , где

ð - знак пробела;

forth_program - программа на языке Форт.

Конструкция позволяет включать произвольные тексты программ на Форте. Для облегчения конструирования действий, описан ряд функций, выполняющих следующие операции:

start-app:ð ApplicationName | запускает синхронно (с ожиданием завершения) приложение ApplicationName
save-attachments:ð FolderName | сохраняет присоединенные файлы в каталоге FolderName (FolderName указывается без завершающего слэша)
[from:ð SenderName] [to:ð RecipientName] [subj:ð subject] message:ð MessageString | генерирует письмо с указанными полями
[from:ð SenderName] [to:ð RecipientName] [subj:ð subject] replay:ð ReplyString | генерирует ответ с указанными полями
replay-with-pattern:ð PatternFileName | генерирует ответ по шаблону PatternFileName

Замечания:

Конструкции message: и replay: идентичны по функии, однако в случае создания ответа на входящее письмо, логично использовать replay:, а для создания нового сообщения - message:. В данных конструкциях фразы from:, to: и subj: могут включаться опционально.

В полях даных команд возможно применение следующих макропеременных:

FROM | адрес отправителя
TO- | адрес получателя
SUBJ | тема письма
BODY | текст письма (если письмо в text/plain)
RAW-BODY | тело письма "как оно есть"
DATE | Текущая дата
TIME | Текущее время
NEW-LINE | Перевод строки
PERCENT | Знак % (процент)

Пример использования макропеременных:

    :- to~ someaddress
            :action to: admin@local message: "somebody got a mail from %FROM%"
    :- to~ myname
            :action to: %FROM% from: %TO-% subj: "RE: %SUBJ%"
                    replay: "I'm not here%NEW-LINE%%DATE%"

Если в конструкциях message: и replay: опускается фраза subj:, в соответствующее поле по умолчанию подставляется макропеременная SUBJ. В поля from и to по умолчанию подставляются макропеременные TO- и FROM соответственно.

Для большей наглядности при организвции автоответчика рекомендуется использовать replay-with-pattern:. При этом шаблон автоответа помещается в отдельный файл. Пример, показаный выше, будет выглядеть следующим образом :

    :- to~ myname
        :action replay-with-pattern: agents\replay1.pat

    -- Содержимое файла replay1.pat : -----------------
    For: %FROM%
    To: %FROM%
    From: %TO-%
    Subject: RE: %SUBJ%

    I'm not here
    %DATE%
    ---------------------------------------------------------------

Запись имен полей в файле шаблона отличается от записи в конструкции действия ! Строки, содержащие пробелы, не заключаются в кавычки. Здесь также необходимо указание поля For:.

Примеры использования start-app: и save-attachments:

    :- from~ administrator subj~ "check viruses" AND
        :action start-app: "drweb.exe c:"

    :- field: "content-deposition" S" attachment" ~match
        :action save-attachments: c:\temp\attachments

### Механизм тоссинга

Если текущее обрабатываемое письмо, в результате срабатывания хотя бы одной группы правил, было направлено в локальный почтовый ящик (==> address), оно получает статус tossed. Если же не сработала ни одна группа условий, в конце схемы тоссинга письмо имеет статус nottossed. Существует функция not-tossed?, возвращающая true для писем, имеющих статус nottossed. Таким образом появляется возможность выполнять специфические действия для писем, имеющих статус nottossed и направлять их в указанный почтовый ящик:

    :- not-tossed?
    ==> mailarchive@local
        :action to: admin@local message: "Пришла какая-то почта" ;

Иногда возникают ситуации, когда необходимо предотвратить прохождение письма через нижестоящие группы правил. Это позволяет делать директива cut.

Пример:

    :- rule1
    :- rule2 cut
    :- rule3
    ==> somebody@local

При срабатывании правила rule2 завершается процесс проверки текущего письма.