[PREVIOUS CHAPTER] [NEXT CHAPTER]
2 libexec/fml_local.pl

2.1	ローカル配送のためのインターフェイス (libexec/fml_local.pl)

ようはループを止めようと思ったものの、作り終わってみたら な〜んか 
slocal と同じになっちゃいましたね(馬鹿)。まぁ tk-slocal とか世の中には
あるんで、perl-slocal があってもいいでしょ(開きなおり(苦笑))

slocalと違うのは、制御するファイルのFieldの数とか、正規表現が使えると
か、(必要なら fml のlibrary を呼び込んで)perlの関数を直接呼べるとか…
という upper compatibility です。

歴史的に(デフォールトでは)「最後にマッチするエントリを実行する」という
ところが決定的に違います。諸葉の都合で、例えば簡単に学習するvacationプ
ログラムへと拡張できるための仕様だったのですが、今となっては設計のミス
のような気がします。設定で

	FIRST_MATCH

とすれば 最初にマッチしたパターンを実行するようになります。slocal なん
かと同じです。

	libexec/fml_local2.pl 

のほうはデフォールトが「最初にマッチしたパターンを実行」するようになっ
ています。
#実は単なるリンクで、自分の名前を見て実行を変えているだけです

2.2	Overview

~/.forward は通常アドレスのフォワードに使われますが、本質的に 
/etc/aliases と同じように作動しますので、ここにプログラムを設定すれば
自動仕分けやこじんまりとした(手抜き)MLを実行することが可能です。

実際の仕分けやプログラムへ渡す前の前処理段階つまりヘッダ等のパターンを
見て何をすればいいのか判定するプログラムが libexec/fml_local.pl です。

	libexec/fml_local.pl
	libexec/fml_local2.pl

と2つありますが、パターンマッチの仕方が違うだけです。後述のように 
fml_local.pl は最後にマッチした条件(以下 LAST MATCH)を実行、
fml_local2.pl は最初にマッチした条件(以下 FIRST MATCH)を実行します。


2.3	fml_local と ~/.forward の設定

~/.forwardに

   "|/usr/libexec/fml/libexec/fml_local.pl -user username || exit 75"

とか書いて使います。username はあなたの account名です。

SYNOPSIS: 
  fml_local.pl [-Ddh] [-f config_file] [-user username]
    -h     this help
    -d     debug mode on
    -D     dump variable 
    -f     configuration file for ~/.fmllocalrc
    -user  username

デフォールトでは $HOME/.fmllocalrc という設定ファイルにしたがってパター
ンマッチングとその処理を実行します。

この時 ~/.fmllocalrc を上から順番にパターンマッチするか?否か?を試し
て“最後にマッチするエントリを実行します”。

これは主に歴史的な理由で last match なのですが、FIRST_MATCH を定義する
か libexec/fml_local2.pl を使えば最初にパターンマッチした処理を実行す
るように変更できます。

以下 LAST MATCH する場合について記述しています。FIRST MATCH の場合は逆
になるので注意して下さい。


2.4	~/.fmllocalrc 

fml_local.pl は ~/.fmllocalrc で制御します。見本が etc/dot_fmllocalrc 
です。

いつものように
	# ではじまる行はコメント
	空行は無視して次へ進む

です。

デフォールトは自分のスプールへ、そしてローカルなMLの配送はスプールへ
落すようにセットしてループしないようにするべきです。

だから、LAST MATCH の場合、最後に必ず

	From		自分	&	MailLocal
	X-MLserver 	\S+	& 	MailLocal

のエントリをかくことがループを防ぐためにもっとも大事になります。

もちろんループを検出した場合は強制的に MailLocal を実行して /var/mail 
等へ入れてしまいます。

さらに、MLをやるときは

	From		自分	&	MailLocal

	# MLの設定
	X-MLserver 	\S+	& 	MailLocal

のように挟んでください。そうしないと自分ではMLへ投稿できません(苦笑)
#後にあると From がマッチしてしまう(last match の場合の例であることに注意)


2.5	~/.fmllocalrc の各フィールド

4つの変数をSPACE or TABで区切ってやってほしいことをかきます。

	フィールド パターン 実行のタイプ 実行すること

です。空行で区切られた各パラグラフが条件文です。

	フィールド1 パターン1
	フィールド2 パターン2 実行のタイプ 実行すること

のように複数行あるパラグラフはANDの条件文です。つまり、上の場合
「フィールド1 パターン1」かつ「フィールド2 パターン2」の条件を満たすな
ら実行する…という意味になります。

それ以外に変数を定義できます。

例:
	HOME	/home/beth/fukachan
	DIR	/home/beth/fukachan
	DEBUG


それらの変数は実行内容の中で展開して使われます。セットされる変数一覧
(@VAR の中身)は後述します(2.10)

また”フィールド パターン”はメールのヘッダのすべての行について、

	if (そのフィールドの値 =~ /パターン/ )

の形で判定されます。つまり

	subject: の特定のキーワードでMLを起動する

や、X-ML: というのをヘッダにつけてもらい

	X-ML:	uja というフィールドがあったらMLを起動する

等の設定も自由自在ます。しかし逆に意識的に設定しない限り

	Subject: uja
	Subject: ujauja
	Subject: Elena Sayori uja uja UJA

等はすべて同じものに見なしてしまいます。


各フィールドの意味は次の通りです。

フィールド	To, subject, 等。なんでもいい。
		body という特別なフィールドもあります
		これはメール本文を仮想的にヘッダのフィールドと同様に扱
		うことで実装しています。

パターン	perlの正規表現が使えます。
		スペースとかは含めないので
		get\s+(\S+) 
		こんな形になります。
		() でマッチした変数は順に
		$F1 $F2 $F3 に設定されます。
		話をややこしくしないために $F1 等はグローバル変数です。

実行のタイプ	& は perl の関数呼びだし
		> は そのファイルにアペンドです
		| は パイプで渡します。
		UNIX FROMつきのまま渡します
		UNIX FROMを抜いた形でプログラムへ渡すには
		|の代わりにmhと書いてください
		(mhへ渡すことを想定している)

実行するもの	実行するもの。関数 or ファイル


パターンマッチルーチンの後 $TYPE と $EXEC というグローバル変数に実行す
るべきタイプと実行するべきプログラムが設定されます。


2.6	パターンの記述に用いることのできる正規表現

以下で実際に出てくる基本的な正規表現をすこし説明します。

	. 	なんでもいいから一文字
	\s 	空白文字 e.g. space TAB 
	\S 	空白でない文字
	+ 	1個以上
	* 	0個以上です。
	\S+	1個以上の空白でない文字列
	.*	0個以上の文字列(なんでもいい)

	()でくくったものがマッチしたもので fml_local.pl では
	左から順番に グローバル変数 $F1 $F2 $F3 にセットされます


2.7	パターンの例

例1:
	to	(uja)		|	$DIR/fml.pl $DIR $DIR

To: フィールドのどっかに uja という文字列があれば、それにマッチする
例えば To: fukachan@sapporo.iij.ad.jp (uja)

なお、
	to	\(uja\)		|	$DIR/fml.pl $DIR $DIR

は uja ではなく (uja)  にマッチします。


例2:

	Subject	get\s+(\S+)	&	sendback

例えば Subject: get GUIDE FILE の GUIDE だけにまっち 

例3:
	body	get my spool (.*)	& 	getmyspool

メール本文に 
	get my spool uja uja
とあれば、"uja uja" の部分を $F1 にセットします。.* だからスペースにも
マッチしてます。これでパスワードに空白も使えますね。


2.8	~/.fmllocalrc でMLを行なう例

LAST MATCH に注意!

MLをセットする ~/.fmllocalrc の例:

   DIR	/usr/local/fml

   From		fukachan	&	MailLocal

   to		\(uja\)		|	$DIR/fml.pl $DIR $DIR

   to		\(sayori\)	|	$DIR/fml.pl $HOME/var/sayori 

   X-MLserver	\S		&	MailLocal


	To: username@somewhere.jp (uja) 
というメールがきたら
	"|$DIR/fml.pl $DIR $DIR" 

という普通の形でMLを作動させるというものです。
ここで $DIR は上の DIR の行の値で展開されます。

このfml.pl は普通のfml.pl です。パッチとかをあてる必要はありません。
つまり、fml_local.pl がヘッダをみて何を起動すればいいかを
判断するので、起動するべきものは普通のMLサーバでいいわけです。

また、 (uja)  は 
	うじゃML(/usr/local/fmlの下にconfig.phでカスタマイズ)を、

(sayori) はまた別の 
	さよりちゃんML(/usr/local/fml/var/sayori/config.ph)

を起動します。

これ以外の、From: fukachan…(@phys とかついてても なくてもいい) や、
X-MLserver: フィールドのあるメール、いづれにもマッチしないメールはすべ
て /var/mail/fukachan のように sendmail が普通スプールする場所にスプー
ルされます。


2.9	フィールドはヘッダ以外に body  があります

これはパスワードを必要とするようなものは、本体でパスワードを書くべきで
す。エラーメールではヘッダはまるみえですから

body	getmyspool\s+(\S+)	&	getmyspool_pw

とか設定すれば、Providerから会社の自分のスプールの内容を夜中に読むとかが
できるようになります。
例:
% echo "getmyspool password-is-required" |Mail 自分のアドレス


2.10	変数一覧

もし変数を明示的にセットしないときは適当な値がデフォールト設定されます。

    @VAR = (HOME, DIR, LIBDIR, FML_PL, USER, MAIL_SPOOL, LOG, TMP,
	    TMP_DIR, PASSWORD, DEBUG, AND, ARCHIVE_DIR, VACATION,
	    MAINTAINER, MAINTAINER_SIGNATURE, FS,
	    LOG_MESSAGE_ID, SECURE_FML_LOCAL,
	    FIRST_MATCH, SLOCAL,
	    MY_FUNCTIONS, CASE_INSENSITIVE, MAIL_LENGTH_LIMIT);

これらの USER DEFINED 変数は fml_local 中ではそれぞれ

	@VAR $HOME $DIR $LIBDIR $FML_PL $USER $MAIL_SPOOL $LOG $TMP
	$TMP_DIR $PASSWORD $DEBUG $AND $ARCHIVE_DIR $VACATION
	$MAINTAINER $MAINTAINER_SIGNATURE $FS $LOG_MESSAGE_ID
	$SECURE_FML_LOCAL $FIRST_MATCH $SLOCAL $MY_FUNCTIONS
	$CASE_INSENSITIVE $MAIL_LENGTH_LIMIT

のような USER DEFINED 変数中に格納され Refer することができます。


# USER	-user fukachan で設定する変数と同じ意味
USER	fukachan

# HOME	$HOME変数。
# Bourne Shell 風にしているので、~/ を展開するようにはなっていません
HOME	/home/axion/fukachan

# fml.pl のある場所。でも使ってない変数…:-)
FML_PL	/home/vivian/fukachan/work/EXP/fml.pl

# $DIR 変数の設定。下で使われると $DIR を次の値で展開するため
DIR	/home/vivian/fukachan/work/EXP

# $LIBDIR 変数の設定。下で使われると $LIBDIR を次の値で展開するため
LIBDIR	/home/vivian/fukachan/work/EXP

# メールスプールの場所
MAIL_SPOOL	/var/mail/fukachan

# デバッグモード
DEBUG

# From: であり、エラーメールが返る場所。もっともふつう〜は
# 自分自身以外に設定仕様がないですね
MAINTAINER 	fukachan@phys.titech.ac.jp

# From: in MAINTAINER's SIGNATURE
# From: $MAINTAINER ($MAINTAINER_SIGNATURE) になる
# e.g. 返るメールのFrom:が、
# From: fukachan@phys.titech.ac.jp (Prisoner No.6 Fukachan)
# になる
MAINTAINER_SIGNATURE	Prisoner No.6 Fukachan

# ログファイル デフォールトは ~/log
LOG		$HOME/work/fml/log

# パスワード
PASSWORD	uja uja 

# get とかで使う アーカイブの置き場所。もし設定してないと HOME
ARCHIVE_DIR	/home/uja/uja/work/archive

# Vacation program compatible で vacation の働きもする。
VACATION	/home/uja/uja/.vacationrc

# フィールドセパレータを変更する
FS	\s+

FS	:
とすれば、.fmllocalrcの設定は From:fukachan:&:MailLocal とかくことになる

# ユーザーが自分用に設定した関数を 別のファイルにしまいたいなら
# そのファイル名を設定する。デフォールトは ~/.myfunctions.pl
MY_FUNCTIONS	/home/your-function-file

INC	include-path

必要なら、fml のいろいろな ライブラリファイルを include してより高度な
関数を使うことが可能です。そのライブラリが置いてある場所を指定します。
いくつ指定してもOKです。
値は指定した順番に @INC に代入されます。そして、その順番にサーチされま
す。

MAIL_LENGTH_LIMIT	2900

getmyspool2 では分割して送り返す関数を呼びます。この分割のしかたで、
何行でファイルを分けるか? をきめます。
たとえば、ヘッダが2、30行あると仮定すると、余裕を見て2900とかし
ておけば、3000行制限のあるBBSでも受け取れるようになるでしょう。


TMPDIR			./tmp

$HOME からの相対パスをかく。デフォールトは ./tmp(つまり $HOME/tmp )
#なければ、つくります。


SECURE_FML_LOCAL	0

最終的に実行されるコマンドのsecurity予備チェック。自分で書いたコードで
も Special character があれば、Insecure となってしまうので、.fmllocalrc 
には特殊も時は使わず、定数を埋め込んだ形で書くのが望ましい。
その上で Secure にするべきであろう。


2.11	フィールド設定の例
_____________________________
#field		pattern		type	exec

# (/usr/libexec/mail.local にならう)
# スプール (例 /var/mail/fukachan )に Appendします
# From:fukachan の場合、From:fukachan@phys.titech...もマッチする
From		fukachan	&	MailLocal

# MH の folder へいれる。MH本来の slocal はこう使うんだろうなぁ
From		fukachan@phys	mh	/usr/local/lib/mh/rcvstore +inbox

# 外国TVシリーズMLからのメールは
# TO:enterprise@phys.titech.ac.jp になるから、それにマッチしたら
# ~/Mail/enterprise というフォルダーにいれる
To		Enterprise@phys mh	/usr/local/lib/mh/rcvstore +enterprise

# File Retrieving 
# perl の関数を呼ぶ。(\S+)でマッチしたものが ↓$F1 に置き換えられる。
Subject		get\s+(\S+)	|	/usr/bin/Mail -s $F1 $From_address

# Exec ML
# MLサーバ fml.pl を呼ぶ。
# 今の場合管理者宛のメールは上のFrom や X-MLserverでスプールに落すので
# ループはしない

to		(uja)		|	$DIR/fml.pl $DIR $DIR


# これは最後にマッチするべき、これで絶対にループしないはず
# MailLocal は
# (/usr/libexec/mail.local にならう)
# スプール (例 /var/mail/fukachan )に Appendします
# From:fukachan の場合、From:fukachan@phys.titech...もマッチする
# From		fukachan	&	MailLocal
# もし ML からきたら、ローカルにおとす
X-MLserver	\S		&	MailLocal

____________________________


2.12	ファイルを送り返す設定の例

~/.fmllocalrc
____________________________
# Subject: get ファイル名
# アーカイブの“ファイル名”のファイルを
# Reply-to: へ もしなければ From: へ送り返す

Subject         get\s+(\S+)     	&	sendback

# Subject: GUIDE
# アーカイブの ファイル GUIDE を
# Reply-to: へ もしなければ From: へ送り返す

Subject         (GUIDE)  	   	&	sendback

# メール本文に "getmyspool パスワード" とかいて
# 家から (大学|会社)のメールスプールを 家に送ってもらう
# 一応スプールのメールは消さない
# Reply-to: へ もしなければ From: へ送り返す

body            getmyspool\s+(\S+)	&	getmyspool_pw

____________________________


2.13	fml_local BUILD-IN Functions 一覧


[PREVIOUS CHAPTER] [NEXT CHAPTER]