2006年06月28日
届いたメールの料理の仕方 (2) 〜qmail編〜
プログラムに処理させたい
まず、dot-qmailの書き方から。
kbora-todo@klab.orgに届いたメールを、コマンド/home/kbora/bin/process-todoに処理させたい場合は~kbora/.qmail-todoにこう書きます。
| /home/kbora/bin/process-todo
行頭を「|」にすると、残りの部分はコマンドとして実行されます。オプションや引数を書くこともできます。
届いたメールの内容は、process-todoの標準入力に渡されます。
例えば、とあるメールアドレスにメールを送ると、メールの内容を社内のグループウェアのToDoリストに追加できる、なんてこともできますね。
環境変数
さて、dot-qmailの中で実行されるコマンドは、いくつかの環境変数がセットされた上で実行されます。これらの環境変数を使うと、送信先アドレスの解析などが楽になります。
セットされる環境変数について、詳しくはqmail-command(8)を参照していただきたいのですが、ひとつだけ覚えておいて欲しいものがあります。
それは環境変数SENDERです。
SENDERにはenvelope fromのメールアドレスがセットされています。通常ならば、メールの送り主であるFrom:ヘッダのメールアドレスと同じものがセットされているのですが、例外があります。
それはバウンスメールのときです。バウンスメールのときは、From:ヘッダはmailer-daemonとかpostmasterとかになっていると思いますが、envelope fromは空(Return-Path: <>)もしくは「#@[]」になります。(後者はqmail独自の仕様で、ダブルバウンスメールの際にこのfromになります)
ですので、コマンドの中で、環境変数SENDERをみて、「」(空文字)もしくは「#@[]」の場合は、それはバウンスメールなので、本処理(ToDoの登録処理とか)ではなく例外処理を行いましょう。
終了コード
dot-qmailから実行されるコマンドの終了コードには意味があります。
詳しくはqmail-command(8)を見て欲しいのですが、簡単に説明するとこうなります。
終了コード | 説明 | 次の配送命令の実行可否 |
---|---|---|
0 | 配送成功。 | 実行する |
99 | 配送成功。 | 実行しない |
100 | 永続的な配送失敗。envelope fromにエラーメールが返る。 | 実行しない |
111 | 一時的な配送失敗。再送キューに入れて後でまた再送を試みる。 | 再送キューに入っている間は実行しない |
「次の配送命令の実行可否」とは、dot-qmailに列挙されている次の配送命令を実行するかどうか、です。
例えば、
| command1
&kbora@klab.org
&ktodo@klab.org
となっている場合に、command1がexit 0した場合は後続の配送命令(&kbora@klab.orgへのメール転送)が行われますが、exit 99した場合は後続の配送命令が実行されない(kboraにもktodoにもメールは転送されない)わけです。
ここでexit 111の場合はちょっと注意が必要で、command1がexit 111するとそのメールは再送キューに入ってあとで再配送されるわけですが、exit 111している間は次の配送命令は実行されません。command1がexit 0してはじめて次の配送命令が実行されます。ですので、command1が何かしらの要因でexit 111している間は待てど暮らせどkboraさんにはメールが来ません。
他に注意したいのはexit 100の場合です。この場合、エラーメールが送信者に返ることになるのですが、そのメール本文には実行したコマンドの標準出力と標準エラー出力が記載されます。迂濶にエラー時のスタックトレースなどを送信者に返すのは好ましくないと思うので、exit 100する際には十分気をつけてください。
次回予告
今回はdot-qmailからコマンドを実行する方法と、その際の環境変数と終了コードについて解説しました。
終了コードによって次の配送命令を実行するか決定できる機能は、うまく使うと便利です。次回はこの機能を使った例を紹介したいと思います。