HDEラボの桜井です。
今年はまともに梅雨入りしてますね。
最近は年のせいか、蛍光灯がちらついて液晶ディスプレイが見にくいです、ってどうでもいいですね。
では、今日はPostfixをハックして、header_checksにコマンドを追加する方法を解説しましょう。
まず、簡単な仕様は次のとおりです。
今年はまともに梅雨入りしてますね。
最近は年のせいか、蛍光灯がちらついて液晶ディスプレイが見にくいです、ってどうでもいいですね。
では、今日はPostfixをハックして、header_checksにコマンドを追加する方法を解説しましょう。
まず、簡単な仕様は次のとおりです。
- メールを指定したディレクトリに保存する機能(いわゆるアーカイブ)を追加する
- header_checksに、「ARCHIVE」というコマンドを追加する
- 「ARCHIVE」コマンドの引数には、メールを保存するディレクトリをフルパスで指定する
まずはソースを持ってきて展開します。
バージョンは最新でいいでしょう。
手を加えるプログラムは下記の4つです。
では、解説行ってみようと思います。
1. "cleanup.h" へ、"ARCHIVE" コマンドのフラグを追加
CLEANUP_STATE構造体へ、下記のフラグを追加します。
2. "cleanup_state.c" へ、"ARCHIVE" フラグの状態の初期化/終了処理を追加
cleanup_state_alloc関数で、CLEANUPO_STATE構造体の初期化を行っています。
ここでフラグの初期化を追加します。
また、cleanup_state_free関数で、CLEANUP_STATE構造体の終了処理を行っています。
ここでフラグの終了処理を追加します。
3. "cleanup_message.c" へ、"ARCHIVE" コマンドと引数取得箇所を追加
cleanup_act関数で、既存コマンドの実行(FILTER、IGNOREなど)を行います。
ここへ "ARCHIVE" の処理を追加します。
4. "cleanup_out.c" へ、ファイルへのメール書き出し処理を追加
cleanup_out関数内で、cleanupコマンドからqueueへのアウトプット処理が行われます。
この中で、メールのファイルへの書き出し処理を追加します(最初の方へ記述します)。
あとはコンパイルして動作させるのみです。
ちなみに、header_checksのファイルへの設定内容は下記のように行います。
(例)example.comから来たメールをすべてアーカイブする場合
一応、2.3.3用に適当にパッチ作ったので(おそらく他のバージョンでも大丈夫な気がする)、 ここからどうぞ。
バージョンは最新でいいでしょう。
手を加えるプログラムは下記の4つです。
- postfix-*.*.*/src/cleanup.h
- postfix-*.*.*/src/cleanup_message.c
- postfix-*.*.*/src/cleanup_out.c
- postfix-*.*.*/src/cleanup_state.c
では、解説行ってみようと思います。
1. "cleanup.h" へ、"ARCHIVE" コマンドのフラグを追加
CLEANUP_STATE構造体へ、下記のフラグを追加します。
char *archive; /* from header/body patterns */
2. "cleanup_state.c" へ、"ARCHIVE" フラグの状態の初期化/終了処理を追加
cleanup_state_alloc関数で、CLEANUPO_STATE構造体の初期化を行っています。
ここでフラグの初期化を追加します。
state->archive = 0;
また、cleanup_state_free関数で、CLEANUP_STATE構造体の終了処理を行っています。
ここでフラグの終了処理を追加します。
if (state->archive) myfree(state->archive);
3. "cleanup_message.c" へ、"ARCHIVE" コマンドと引数取得箇所を追加
cleanup_act関数で、既存コマンドの実行(FILTER、IGNOREなど)を行います。
ここへ "ARCHIVE" の処理を追加します。
if (STREQUAL(value, "ARCHIVE", command_len)) { if (*optional_text == 0) { msg_warn("ARCHIVE action without text in %s map", map_class); return (buf); } else { if (state->archive) { myfree(state->archive); } char archive_filename[1024] = ""; strcat(archive_filename, mystrdup(optional_text)); strcat(archive_filename, mystrdup(state->queue_id)); state->archive = mystrdup(archive_filename); msg_warn("ARCHIVE debug : file=%s, size=%d", archive_filename, sizeof(archive_filename)); msg_warn("ARCHIVE debug : cleanup_path=%s, sender=%s, recip=%s, archive=%s", mystrdup(VSTREAM_PATH(state->dst)), mystrdup(state->sender), mystrdup(state->recip), state->archive); cleanup_act_log(state, "archive", context, buf, optional_text); return (buf); } }
4. "cleanup_out.c" へ、ファイルへのメール書き出し処理を追加
cleanup_out関数内で、cleanupコマンドからqueueへのアウトプット処理が行われます。
この中で、メールのファイルへの書き出し処理を追加します(最初の方へ記述します)。
if (state->archive != 0) { msg_warn("DEBUG message : %s : %s", state->archive, string); int archive_fd = open(state->archive, O_WRONLY | O_CREAT | O_APPEND, 0666); write(archive_fd, string, strlen(string)); write(archive_fd, "\n", 1); close(archive_fd); }
あとはコンパイルして動作させるのみです。
ちなみに、header_checksのファイルへの設定内容は下記のように行います。
(例)example.comから来たメールをすべてアーカイブする場合
/^From: .*example.com/ ARCHIVE /etc/postfix/archive/
一応、2.3.3用に適当にパッチ作ったので(おそらく他のバージョンでも大丈夫な気がする)、 ここからどうぞ。
Leave a comment