fml がメールを読みこむ際のキューイング fmlの各プロセスは MTA から起動され、STDIN(標準入力)からメールを読みこ みます。 fml は、いったんメールを読みこみ、まずはディスクに書き込みます (incoming queue へ書き込む)。書き込みに成功した場合、その書き込んだファ イルに対してメッセージの解析をスタートします。これにより、少なくとも読 みこんだオリジナルのメールの記録は残せます。 もし、失敗した場合、exit(EX_TEMPFAIL)します。たいていの OS では exit(75) です。このエラーコードをうけとると、MTA は一時的なエラーがお こったとみなすため、このメッセージの再送処理を試みてくれます。 incoming queue の処理は Mail::Delivery::Queue を使い、ML固有の queue で管理されます。一連の処理が終ると、たいてい、そのプロセスの最後に、 このキューは消されます。 fml からメールで返事を送り返す 送り返すべきメールは Mail::Delivery::Queue を使いML固有の queue に入れます。 queue に入ったメールは、のちに FML::Process::QueueManager クラス経由で(配送)処理をします。 微妙に処理が異なりますが、記事の配送もコマンドメールも同様に Mail::Delivery::Queue ベースのキューイング処理をしています。そのため、 配送処理の途中でエラーが起きた場合、別のfmlプロセスにより再送処理が行 なわれます。 fml の中ではどう書くのか? あるメッセージ(テキストメッセージ)を送り返したい場合は、次のように書きます。 $curproc->reply_message( "you are not a ML member." ); この場合の受信者はコマンドの結果などを受けとる人、 fml にリクエストをした人です。 ファイルを送りたい場合や画像ファイルを送りたい場合は次のようにします。 $curproc->reply_message( { type => "text/plain; charset=iso-2022-jp", path => "/usr/local/etc/fml/main.cf", filename => "main.cf", disposition => "main.cf example", }); $curproc->reply_message( { type => "image/gif", path => "/some/where/logo001.gif", filename => "logo.gif", disposition => "attachment", }); mail queue と配送の仕組み FML::Process::QueueManager により 特定の queue ファイルが queue ディレクトリから pickup され、 Mail::Message で parse され、 FML::Mailer 経由で Mail::Delivery が実際にメール配送処理をします。 Mail::Delivery::Queue ↓ ↓→→→ キューディレクトリ ↓ FML::Process::QueueManager ↓ ↓←←← キューディレクトリ ↓ FML::Mailer ↓ Mail::Delivery キューを操作する際には、対象のキューを flock(2) します。ロックを他の ATOMIC 操作を使って実装してもよいのですが、 操作途中に OS が逝ってしまうケースを想定すると、 やはり flock(2) を使うべきでしょう。 mail queue ディレクトリ queue ディレクトリは複数のディレクトリからなります。 new/ active/ incoming/ deferred/ info/sender/ info/recipients/ info/transport/ info/ には envelope 情報が格納されます。 また incoming/ は incoming queue ですが、それ以外のディレクトリは outgoing 用です。 queue ファイルを作る時は、一旦 new/ に作成します。 queue ファイルを作る作業が終了し、配送準備 OK となったら new/ から active/ に移動されます。 つまり active/ にあるファイルは配送準備ができているものです。 queue ディレクトリをロックする 特定の $queue_id object ごとに lock() と unlock() メソッドを使い、 ロックをかけます。 ロックは active/$queue_id ファイルに対しての flock(2) システムコールです。