読者です 読者をやめる 読者になる 読者になる

uzullaがブログ

uzullaがブログです。

俺のみ得、xmailで外部プログラムを起動して云々するのメモ

チート

xmailってメールサーバーしってますか?しらない?
割と便利…いや、楽ですよ!

やりたい事

あるドメインに届いたメールを、全部プログラムに喰わせて、空メールとばしたり色々したい。
xmailはまったくUNIXの常識では考えられないセンスで作成されているので、悩ましいですね。


答え

MailRoot/custdomains/my.domain.name.jp.tab

とかつくって、

"external" "1" "30" "/path/to/xmailwrapper.pl" "/path/to/import.pl" "$(FILE)"

などと書く


解説

上記の文法は、http://www.xmailserver.jp/documentation/xmail/commandtab.html とかを読んで下さい。
簡単に端折って言えば、タブ区切りのフィールドを順番に説明すると、
1:external (外部プログラム呼び出し、これは固定)
2:優先度(1でいいのでは…)
3:プログラムタイムアウト、秒
4:xmailが起動するプログラム
5:4のプログラムが受け取る引数1(後述)
6:4のプログラムが受け取る引数2($(FILE)は、メッセージ本体が書かれたテンポラリファイルパス)
です。


引数1の/path/to/import.plは、よくあるメールを標準入力を受け取ってなんかするプログラムです。
これは特に解説しません、空メールとかでググればでるんじゃないですかね。


/path/to/xmailwrapper.pl これは、引数を二つ受け取り、一つめの引数のパスのプログラムを起動して、二つめのパスのファイルを標準入力にながしこむ、というプログラムです。
具体的には以下なかんじ。

#!/usr/bin/perl
open(my $fh, "|-", $ARGV[0]) or die $!;
open(my $ifh, "<", $ARGV[1]) or die $!;
$flag = 0;
while(<$ifh>){
    if($flag){
        print $fh $_;
    }
    if($_=~/<<MAIL-DATA>>/){
        $flag=1;
    }
}


$(FILE)で受け取れるファイルは、先頭5行(なのかどうかしらないが)にゴミがあります。
なので<<MAIL-DATA>>までスキップしています。

xmailwrapper.plいらなくね?

そうですね、いらないですね。これは私のメモです。
UNIXの一般的なMTAはSTDINを受け取って云々させますが、xmailはまったくUNIXの流儀とか無視してますので…。
他の所で使ってるプログラムを流用するために、こういうラッパーを書いてます。

その他注意

プログラムがコケようとなにしようとxmailはエラーを返しません(なので、エラーが帰ってこない=成功!ではない)普通エラーメール返すけど…まあxmailは変わったセンスのプログラムなので。
これは不意にゴミが帰らないという意味では、とてもいいっちゃいいんですけど、開発中は結構かったるい。
xmail自体が絶望的にログを出さない設計なので、がんばりましょう。

おい、お前一回休みやぞ!

use strict;!!!!!!!*1

*1:Parumonでググろう