Postfix 3.0 から導入された動的データベースプラグイン機構を使用して、独自のルックアップテーブルを作ってみます。
Postfix を次のようにしてインストールしてあります。
重要なのは dynamicmaps=yes
なので、これさえあれば他のパラメータ指定はなんでもいいです。
% make makefiles dynamicmaps=yes\ command_directory=/usr/local/postfix/sbin\ config_directory=/usr/local/postfix/etc\ default_database_type=hash\ daemon_directory=/usr/local/postfix/libexec\ data_directory=/var/local/postfix/lib\ html_directory=no\ mail_spool_directory=/var/mail\ mailq_path=/usr/local/postfix/bin/mailq\ manpage_directory=/usr/local/man\ meta_directory=/usr/local/postfix/etc\ newaliases_path=/usr/local/postfix/bin/newaliases\ queue_directory=/var/local/postfix/spool\ readme_directory=no\ sendmail_path=/usr/local/postfix/sbin/sendmail\ shlib_directory=/usr/local/postfix/lib % make % sudo make install % sudo cp -r include /usr/local/postfix/
ルックアップテーブルは与えられた文字列に対して一つの値を返します。
今回は与えられた文字列中の小文字を大文字に変換して返すようなルックアップテーブルのプラグインを作成してみます。
#include "sys_defs.h" #include "dict.h" /* name に対応する値を返す */ static const char *dict_upcase_lookup(DICT *dict, const char *name) { static char buf[256]; int i = 0; /* 256バイト以上の文字列に対する値は見つからなかったことにする */ if (strlen(name) > 255) { return NULL; } while (*name) { buf[i++] = toupper(*name++); } buf[i] = '\0'; return buf; } /* 終了 */ static void dict_upcase_close(DICT *dict) { dict_free(dict); } /* 初期化 */ DICT *dict_upcase_open(const char *name, int open_flags, int dict_flags) { DICT *dict; dict = dict_alloc("upcase", name, sizeof(DICT)); dict->lookup = dict_upcase_lookup; dict->close = dict_upcase_close; dict->flags = dict_flags; return dict; }
作成
% gcc -I /usr/local/postfix/include -fPIC -g -O -DLINUX3 -c dict_upcase.c % gcc -shared -o postfix-upcase.so dict_upcase.o # sudo cp postfix-upcase.so /usr/local/postfix/lib
設定 [/usr/local/postfix/etc/dynamicmaps.cf]
upcase postfix-upcase.so dict_upcase_open
作成したライブラリのファイル名と初期化関数を dynamicmaps.cf に登録します。
shlib_directory
以外の場所に置くこともできます。その場合はフルパスで記述します。
postmap コマンドで試してみます。
% /usr/local/postfix/sbin/postmap -q hoge upcase:dummy HOGE
ちゃんと動いてるようです。
ルックアップテーブルは hash:/etc/aliases
のように type:name
の形式で指定します。
今回は name
部分は特に使用していませんが、初期化関数の第一引数として渡されるので、必要な場合はそれを使えばいいです。