1. 概要
メーリングリストで以下のような半モデレートのポリシーを実現するためのPerlスクリプトをご紹介します。
- 通達、案内、情報紹介などの新たなトピックのメールは、メンバーは誰でも投稿でき、即時配信される(非モデレート)。
- 配信されたメールに対する返信の投稿は、元の投稿者以外のメンバーにとっては無駄な情報(会合案内に対する出欠回答など)の配信や、議論の紛糾を防ぐために、メーリングリスト管理者が承認したものしか配信しない(モデレート)。
- ファイルが添付されたメールや本体が大きすぎるメールは、サーバの過負荷を防ぐために、メーリングリスト管理者が承認したものしか配信しない(モデレート)。
このスクリプトは、既存のメーリングリストプログラムの前段で、投稿メールをメーリングリストプログラムに受け渡すかメーリングリスト管理者へ送るかを制御します。メーリングリスト管理者へ送られたメールは、メーリングリスト管理者が転送で再投稿することによって配信されます。
なお、適用対象のメーリングリストは活発な議論を目的とするものでなく、そのため、配信されるメールに、メーリングリストに返信させるためのReply-Toヘッダが付かないことを前提とします。
2. スクリプトの仕様
このスクリプトは、以下のすべての条件を満たす投稿メールを即時配信のためにメーリングリストプログラムに受け渡します。
- Toヘッダにメーリングリストアドレス一つだけが指定されている。
(メーリングリストで配信されたメールに対する「全員宛返信」の操作で投稿されたメールは、メーリングリストアドレスはCCに、またはメーラーによってはToに元の投稿者のアドレスとの併記で指定されているため、この条件を満たさなくなります。)
- ファイルが添付されていない(ヘッダに「Content-Type: multipart/mixed」がない)。
- メール本体が30,000バイト以下である。
(UUENCODE形式が埋め込まれているか本文が長くて本体が大きすぎる場合を判定するためのサイズ制限です。プレーンテキストでおおむね日本語文字36字/行×370行以下となります。)
条件を満たさない投稿メールは、メーリングリスト管理者へ送られます。メーリングリスト管理者へ送られた投稿メールをメーリングリスト管理者が承認して転送で(必要ならば添付ファイルをはずして)再投稿すると、上記の条件にかかわらず配信します。
その際、メーラー
Becky!の「手を加えずに転送」の機能を使うと、Date、From、To、CC、Subject、本文は元のままとして転送でき(マルチパート形式の添付ファイルをはずすことは可能です)、再投稿したメーリングリスト管理者のアドレスはResent-Fromヘッダに記録されます。そこでこのスクリプトは、Resent-FromをFromに優先して投稿者のアドレスとして認識するようになっています。
なお、ポリシーに反して返信メールのToが細工されても返信メールだと見破りたいならば、In-Reply-Toヘッダがあるかどうかでチェックする方法があります。ただ、他のメールを返信操作で引用して新たなトピックとして投稿されたメールが即時配信されなくなるので、意図的にポリシーに反することをしない善良なメンバーばかりのメーリングリストでは、そこまでのチェックはしない方がよいと思います。
3. 設定方法
メーリングリストアドレスは<
society@example.jp>で、従来はMajordomoで運用されていたと仮定します。メーリングリスト管理者は2人で、アドレスは<
taro@example.jp>および<
hanako@example.jp>と仮定します。本スクリプトのファイルは/usr/local/ml-scripts/
societyと仮定します(ディレクトリ位置やファイル名は任意です)。
/etc/aliasesで、メーリングリストの従来のエイリアス定義をコメントアウトし、代わりに本スクリプトを指定します。赤字の部分を実際のメーリングリスト名やメーリングリスト管理者名に置き換えてください。
/etc/aliasesの設定
#society: "|/usr/local/majordomo/wrapper resend -l society society-outgoing"
society: "|/usr/local/ml-scripts/society"
society-outgoing: :include:/usr/local/majordomo/lists/society
owner-society: taro, hanako
society-request: owner-society
society-owner: owner-society |
4. スクリプトコード
下記のスクリプトコードをドラッグしてファイルにコピー・貼り付けし、赤字の部分を書き換えて使ってください。
メーリングリスト管理者が1人だけの場合は、投稿者アドレスを判定する条件式から、2つ目の「$from =~ /…/ ||」の行を削ってください。複数人の場合は、OR条件でつないで何人でも指定できます。
即時配信の条件判定で、返信メールでないことを厳しくチェックしたい場合は、コメントアウトされている行をコメント解除してください。
なお、MTA(Mail Transfer Agent)はsendmailかPostfixであることを前提としています。
#!/usr/bin/perl
$/ = "";
$_ = $header = <STDIN>;
s/\n[ \t]+/ /g;
if (/(^|\n)Resent-From: (.*)/) {
$from = $2;
}
elsif (/(^|\n)From: (.*)/) {
$from = $2;
}
if (/(^|\n)To: (.*)/) {
$to = $2;
}
$to =~ s/"[^"]*"//g;
if (/(^|\n)Content-Type: (.*)/) {
$content_type = $2;
}
$/ = "\n";
$body = "";
while (<STDIN>) {
$body .= $_;
}
if ($from =~ /\btaro\@example\.jp\b/ ||
$from =~ /\bhanako\@example\.jp\b/ ||
($to =~ /^[^@]*\bsociety\@example\.jp\b[^@]*$/ &&
# !($header =~ /(^|\n)In-Reply-To:/) &&
!($content_type =~ /multipart\/mixed/) &&
length($body) <= 30000)) {
open(MAIL, "|/usr/local/majordomo/wrapper resend -l society society-outgoing");
print MAIL "$header$body";
close(MAIL);
}
else {
open(MAIL, "|/usr/lib/sendmail -oi -f owner-society\@example.jp owner-society\@example.jp");
print MAIL "$header$body";
close(MAIL);
} |
おことわり 既存のメーリングリストプログラムとして、広く使われているMajordomoを前提としましたが、私はMajordomoを使う場合の設定・動作確認をしていません。もし記述に誤りがありましたら
ご連絡ください。
付記 メーリングリスト管理者へ送られた投稿メールを、メーリングリスト管理者がメーラー
Becky!の「手を加えずに転送」の機能を使って再投稿すると、Date、From、To、CC、Subject、本文は元のままになるので、配信されるメールはあたかも、Majordomoなどのメーリングリストプログラムのモデレート機能による保留が解除されて配信されたかのように見えます。しかし、Becky!を使っていなくても、通常の転送による再投稿で、本スクリプトによる半モデレート・ポリシーの運用は可能です。その際、元の投稿者のアドレスをReply-Toに指定して、本文に
「○○さんからの投稿です。添付されていたファイルをhttp://…に掲載しました。このメールへの返信先は○○さんになります。」
のような説明を書き加えることを推奨します。