МЦНМО МОСКОВСКИЙ   ЦЕНТР
НЕПРЕРЫВНОГО  МАТЕМАТИЧЕСКОГО  ОБРАЗОВАНИЯ
Rambler's Top100

Используем procmail для управления почтой.

Основные функции.

Procmail читает конфигурационный файл .procmailrc, который должен находиться в корне пользовательского каталога (/usr/home/username/.procmailrc). В этом файле определяются некоторые правила, которые указывают procmail, какие действия надо предпринять после получения сообщения. Он может решить, что с ним делать: сохранить его, игнорировать, автоматически ответить и т.д., --- проверив некоторые строки в заголовке сообщения.

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

Для удобства в конце этого текста приведен пример конфигурационного файла.

Конфигурация.

  1. MAILDIR Указывает на каталог, в котором procmail сохраняет файлы с почтовыми сообщениями. Обычно эта переменная указывает на $HOME/mail или $HOME/Mail. Тот или иной каталог, зависит от используемого почтового клиента.
  2. LOGFILE Указывает на имя лог-файла, в котором procmail записывает все выполненные операции.
  3. SENDMAIL Указывает на то, где найти sendmail, который используется для автоматического ответа на сообщения.
  4. FORMAIL Указывает на то, где найти formail. Эта программа распространяется вместе с procmail, и её задачей является изменение почтовых заголовков или переформатирование сообщения для отправки или сохранения.
  5. DEFAULT Файл, в котором сохраняется сообщение, если procmail не может применить к нему ни одного определённого правила.

Определять переменную окружения можно в любом месте .procmailrc. Если переменная записана без символа "=", за которым следует значение, то такая переменная удаляется.

Что касается правил, то они делятся на две группы: на те, которые предполагают, что после их применения сообщение доставлено (и дальнейшей обработки сообщения проводить не надо), и остальные.

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

Общий синтаксис правила следующий:

        :0 [опции] [ : [исполняемый файл] ]
        * условие 1 
        * условие 2 
        . 
        . 
        . 
        * условие N
        команда

Пройдемся по каждой части и проанализируем ее конструкцию. Прежде всего, каждое правило начинается с :0, после этого могут следовать любые из этих опций:

По умолчанию, если не была указана ни одна опция, условие применяется к заголовку сообщения (опция H). На стандартный вход команды поступает и заголовок и тело сообщения (опции h и g). Верхний и нижний регистры не различаются. После ":0" и возможных опций может следовать второе ":". Это указывает на то, что файл назначения, куда должно быть записано сообщение, должен быть блокирован во избежание ситуации, когда два процесса одновременно пишут в один файл. Можно указать файл, который будет использован в качестве блокирующего.

Далее идут условия, по одному в строке, и перед каждым ставится символ "*". Условия обычно записываются в виде регулярных выражений для того, чтобы определить последовательность символов в заголовке или теле сообщения. Регулярное выражение среди прочих использует следующие символы:

После условий идет одна команда. Если первый символ команды является одним из приведенных ниже, то предполагается особое поведение:

Списки рассылки (mailing lists)

Управление вашей почтой — это та ситуация, когда procmail может быть очень полезен. Предположим, что мы подписаны на три списка рассылка по Линукс, и каждый список идентифицируется по адресу отправителя, например у нас могут быть следующие адреса

        l-linux@calvo.teleco.ulpgc.es 
        linux@nuclecu.unam.mx 
        linux-security@redhat.com 

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

Procmail решает эту проблему просто. Мы можем использовать файл .procmailrc со следующими очень простыми правилами сортировки нашей почты из различных списков рассылки по Линукс:

        :0 
        * ^From.*l-linux@calvo.teleco.ulpgc.es 
        l-linux 

        :0 
        * ^From.*linux@nuclecu.unam.mx 
        linux-mx 

        :0 
        * ^From.*linux-security@redhat.com 
        linux-security 

Внимательно исследуем одно из этих правил. Если вы поймете внутренний принцип работы какого-либо правила, то легко будет понять остальное, поскольку основной механизм остается прежним.

В начале находится строка ":0", которая обозначает начало нового правила. Других опций не указано, поэтому для этого правила procmail берет опции по умолчанию: верхний и нижний регистры не различаются, условие применяется только к заголовку почты, команда обрабатывает и заголовок и тело сообщения.

В следующей строке находится условие, которое, поскольку оно упоминалось прежде, всегда распознаётся, так как первым стоит символ "*". Условие является следующим регулярным выражением:

        ^From.*linux@nuclecu.unam.mx

Подстрока "^From" указывает procmail на то, что необходимо искать эти строки следом за подстрокой "From".

Следующий символ ".*" означает любое количество символов. Ранее мы отметили, что в регулярном выражении символ "." эквивалентент любому символу, а "*" обозначает ноль или больше. Следовательно ".*" означает, что после начального "From" может быть ноль или более символов.

Дальше идет строка "linux@nuclecu.unam.mx", которая является адресом, с которого пришло сообщение.

Подумав немного над этим регулярным выражением, вы поймёте, что это правило "вычислит" следующие строки:

        From: linux@nuclecu.unam.mx 
        From:linux@nuclecu.unam.mx 
        FROM linux@nuclecu.unam.mx

Используя это правило, уже можно различать сообщения, приходящие с этого адреса, и остальные. Что же теперь нужно сделать с сообщением?

Следующей строкой является команда (или действие), и оно указывает, что делать с сообщением. В этом случае предполагается сохранить его в файле "linux-mx". Если абсолютный путь к файлу не указан, по умолчанию принимается, что он добавляется к переменной окружения $MAILDIR.

Очевидно, сообщения приходящие из различных списков теперь можно распределять по различным файлам, в зависимости от адреса отправителя (поле From).

Автоматический ответ

Другой ситуацией, в которой procmail может пригодиться, являются автоответчики. Часто очень удобно, например, если вы хотите автоматически отправить ваш публичный ключ PGP любому, запросившему его по E-Mail.

Чтобы это сделать, напишите правило, которое считает запросом вашего ключа PGP любое собщение, в строке subject которого есть строка PGP. Это правило можно записать как:

        0:
        * ^Subject.*PGP
        | (formail -r ; cat $HOME/key.asc)
        | sendmail -t
Та же самая идея используется для написания обычной программы, которая сообщает людям о том, что мы в отпуске и ответим на их почтовое сообщение по возвращении:
        0:
        | (formail -r; cat $HOME/vacations.txt)
        | sendmail -t 

В последнем случае условий нет, так как на все сообщения будут отправлены одни и те же ответы.

Как избежать зацикливания автоответчика.

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

Если в сообщении адресом отправителя является наш собственный E-Mail адрес, и программа должна ответить на этот адрес, то ответ вернётся к нам же. На это сообщение следует ещё один ответ и так далее до бесконечности. Чтобы этого избежать, при ответе на сообщение нужно добавить дополнительную строку к заголовку, чтобы указать, что на это сообщение уже отвечали. Используется опция -A formail:

        formail -r -A"X-Loop: qwerty@mccme.ru"

Здесь qwerty@mccme.ru будет нашим собственным E-Mail адресом. В этом случае при создании заголовка ответа добавляется строка X-Loop с тем, чтобы позднее можно было проверить новым правилом:

 
        :0 
        * !^X-Loop: qwerty@mccme.ru 
        | (formail -r -A"X-Loop: qwerty@mccme.ru" ;  
           cat $HOME/vacation.txt) | sendmail -t 

Это правило предотвращает зацикливание, так как любое собщение, содержащее в заголовке строку X-Loop, не будет удовлетворять условиям, и в результате procmail на него не ответит.

Декодирование файлов.

Ещё одним интересным правилом нашего ".procmailrc" может быть декодировка поступающей почты, автоматически закодированной uuencode(1). Это правило можно задать как:

 
        :0 B 
        * ^begin 644 .* 
        { 
                MAILDIR=$HOME/files 
         
        :0 
                | uudecode 
        } 

Здесь явно задано опцией B, что условие правила должно применяться только к телу сообщения.

Если правило находит строку, начинающуюся со строки "begin 644", то это означает, что это начало файла, закодированного uuencode(1), поэтому устанавливается переменная окружения MAILDIR, что эквивалентно изменению каталога, на который указывает эта переменная. С этого момента все действия по выводу сообщений будут выполняться с учётом указанного базового каталога. В нашем случае нам необходимо, чтобы поступающие сообщения сохранялись в $HOME/files.

Дальше идёт правило, безусловное, которое только направляет сообщение в канал для декодирования. Исходный файл будет отправлен в $HOME/files.

Пример файла ".procmailrc".

Внимание! Права на файл .procmailrc должны быть выставлены "600"!


Если вы заметили ошибку на этой странице, напишите нам <compwww (at) mccme.ru>