Встроенный perl

Перевод выполнен Алексеем Паутовым в рамках некоммерческого проекта RussianLDP (http://www.rldp.ru/). Именно на этом сайте и надлежит искать новые версии, если таковые будут.

12. Встроенный perl

Exim может быть собран с встроенным интерпретатором perl. Когда это сделано, подпрограммы perl можно вызывать как часть процесса раскрытия. Для использования поддержки perl Вам нужна установленная в системе версия 5.004 или более поздняя. Для включения встроенного интерпретатора perl в исполняемый файл exim включите строку:

EXIM_PERL = perl.o
в Ваш Local/Makefile, а затем соберите exim обычным способом.

12.1. Настройка использования perl

Доступ к подпрограммам perl осуществляется через глобальную конфигурационную опцию perl_startup и оператор раскрытия ${perl ...}. Если опция perl_startup отсутствует в конфигурационном файле exim, тогда интерпретатор perl не запускается, и для exim почти нет накладных расходов (так как ни одна библиотек perl не использует страницы памяти). Если опция perl_startup присутствует, ассоциированное значение берётся, чтобы быть кодом perl, выполняемым в созданном интерпретаторе.

Значение perl_startup не раскрывается в смысле exim, таким образом, Вам не нужно добавлять символ обратного слэша перед символами имеющими специальное значение. Опция обычно выглядит так:

perl_startup = do '/etc/exim.pl'
где /etc/exim.pl код perl, определяющий любые подрограммы, которые Вы хотите использовать с exim. Exim может быть сконфигурирован для запуска интерпретатора perl сразу или ждать первого раза, когда он понадобиться. Старт интепретатора в начале гарантирует, что действие будет сделано в то время, когда exim имеет setuid привилегии, но может вызвать ненужные накладные расходя, если perl, фактически, не используется в выполняемой части. Кроме этого, отметьте, что это не означает, что exim работает от root при вызове perl в более поздние моменты времени. По умолчанию интерпретатор запускается только когда он необходим, и это может быть изменено в двух местах:
  • Установкой опции perl_at_start (булева опция) в конфигурации запрашивается запуск при начале работы exim.
  • Опция командной строки -ps также вызывает запуск вместе с exim, отменяя установку perl_at_start.

Также есть опция командной строки -pd (для задержки), подавляющая начальный запуск, даже если установлена опция perl_at_start.

12.2. Вызов подпрограмм perl

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

${perl{foo}}
${perl{foo}{argument}}
${perl{foo}{argument1}{argument2} ... }
вызывающих подпрограмму foo с заданными параметрами. Может быть передано максимум восемь параметров. Передача большего числа приводит к ошибке раскрытия с сообщением об ошибке такой формы:
Too many arguments passed to Perl subroutine "foo" (max is 8)

Возвращаемое значение подрограммы perl оценивается в скалярных величинах до возвращения его exim, чтобы быть вставленным в раскрытую строку. Если возвращённое значение undef, раскрытие терпит принудительную неудачу таким же образом, как и явный fail в элементе if или lookup. Если подпрограмма прерывается, повинуясь функции perl die, раскрытие неудачно с сообщением об ошибке, которое передано die.

12.3. Вызов функций exim из perl

Внутри любого кода perl, вызыванного из exim, доступна функция Exim::expand_string() для обратного вызова в функцию раскрытия exim. Для примера, код perl:

my $lp = Exim::expand_string('$local_part');
сделает текущую переменную exim $local_part доступной в переменной perl $ip. Отметьте, что тут одиночные кавычки, а не двойные, для предотвращения интепретации $local_part как переменной perl.

Если раскрытие строки принудительно сделано неуспешным, элементом fail, результат Exim::expand_string(): undef. Если в строке раскрытия есть синтаксическая ошибка, из оригинального раскрытия строки вызывается ошибка perl, с соответствующим сообщением об ошибке, таким же образом, как будто использовалось die.

Внутри кода perl доступны две другие функции exim. Exim::debug_write() записывает строку в стандартный поток ошибок, если включена отладка exim. Если Вы хотите добавлять в конец строки символ новой строки, Вы его должны подставить. Exim::log_write() пишет строки в основной протокол exim, добавляя в начале метку времени. В этом случае Вам не нужно добавлять перевод строки.

12.4. Использование стандартного вывода и ошибок perl

Вы не должны записывать в стандартный поток ошибок, или стандартный вывод изнутри Вашего кода perl, поскольку не заданы их установки. В версиях exim до 4.50 это возможно для стандартного вывода или стандартного потока ошибок для ссылки на SMTP-соединение в течение приёма сообщения демоном. Запись в этот поток вызывает хаос. С exim 4.50 стандартные потоки ошибок и вывода соединены с /dev/null в демоне. Хаос отсутствует, но вывод потерян.

Утверждение perl warn по умолчанию пишется в стандартный поток ошибок. Вызовы warn могут быть встроены в модули perl, которые Вы используете, но которые не контролируете. Когда exim запускает интерпретатор perl, он принимает меры для записи вывода утверждений warn в главный лог exim. Вы можете изменить это путём включения соответсвующей опции perl где-то внутри его кода. Например, чтобы полностью отказаться от вывода warn, необходимо это:

$SIG{__WARN__} = sub { };

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