<!--
   $FML: config.cf.sgml,v 1.16 2008/08/18 13:21:42 fukachan Exp $
-->


<chapter id="internal.config.cf">
	<title>
	設定ファイル config.cf
	</title>


<!-- ======================================= -->
<sect1 id="config.cf">
	<title>
	ＭＬごとの設定ファイル config.cf
	</title>

<para>
各ＭＬごとにさまざまなカスタマイズをすることができます。
この点は &fml4; でも &fml8; でも同様です。
</para>

<para>
そのために &fml4; では各ＭＬのホームディレクトリ $DIR (例:
/var/spool/ml/elena)に config.ph というファイルがあります。
これは .ph という名前でわかる通り perl script です。
</para>

<para>
一方 &fml8; では config.cf というファイルです。
フォーマットは Postfix や .ini 風の
<screen>
変数 = 値
</screen>
形式になっています。
複数行の値も可能です(後述)。
</para>

<para>
perl module と同様に、=cut の後には perl script を書くようになっています。
「キーワード = 値」形式の記述は =cut の前に書いて下さい。
</para>

<sect2>
	<title>
	&fml4; の諸問題
	</title>

<para>
&fml4; の perl script 方式には、いくつか問題があります。
</para>

<para>
メリットとしては、
perl script なので、perl が許す限りの自由な書き方ができます。
これは人間にとっては嬉しいのですが、
機械処理の観点からは問題です。というのは 
makefml や CGI をはじめとする設定インターフェイスを書きにくいのです。
そこで &fml4; では、
cf というファイルと config.ph という
2 つのフォーマットの異なるファイルが使われることになりました。
<footnote>
<para>
.mc から .cf を作る点で、なんとなく sendmail みたいですね;)
</para>
</footnote>
しかし、これでは２つのファイルに分かれてしまう点で保守がしにくくなります。
</para>

<para>
よって &fml8; では、
設定インターフェイスにやさしい新フォーマットとしました。
それが config.cf で、
本質的に Postfix 風フォーマットです。
</para>

</sect2>
</sect1>


<!-- ======================================= -->
<sect1 id="config.cf.format">
	<title>
	config.cf のフォーマット
	</title>

<para>
config.cf のフォーマットは
	<link linkend="main.cf">
	/usr/local/etc/fml/main.cf
	</link>
と同様です。
<screen>
変数名 = 値

変数名 = 値1 値2 値3

変数名 = 値1
         値2
         値3
</screen>
のようにスペースないしは改行で区切って複数の値を書くことができます。
</para>

<para>
変数定義内での $ による変数の展開も可能です。
たとえば
<screen>
a = 値1
b = $a/値2
</screen>
は最終的に
<screen>
a = 値1
b = 値1/値2
</screen>
と解釈されます。
</para>


<para>
展開は、すべての変数定義を読みこんだ後に行なわれます。
そのため、以下のように定義をすると
<screen>
a = 値1
b = $a/値2/$c
c = 値3
a = 値4
</screen>
すべてを読み込んだあとに解釈されるため
<screen>
b = 値4/値2/値3
</screen>
と判断されます。
</para>

</sect1>


<!-- ======================================= -->
<sect1 id="config.cf.format.extension">
	<title>
	Postfix スタイルのさらなる拡張
	</title>

<para>
<screen>
変数名 += 値
変数名 -= 値
</screen>
で、特定の値の足し引きができます。
</para>

<para>
<screen>
x  = a b c d
x -= b
</screen>
は
<screen>
x = a c d
</screen>
と解釈されます。
</para>

<para>
また
<screen>
x  = a b c d
x += e
</screen>
は
<screen>
x = a b c d e
</screen>
となります。
</para>

</sect1>


<!-- ======================================= -->
<sect1 id="config.cf.overload">
	<title>
	config.cf の多重読み込み(変数定義の上書き)
	</title>

<para>
複数の config.cf を読み込み、定義の上書きを行なうことができます。
</para>

<para>
これを利用して
『デフォルトの定義』、
『サイト固有の定義』、
『ドメイン固有の定義』
などを別ファイルに分離し、
上書きしつつ多重読み込みをすることができます。
このために、デフォルトでは、いくつかの .cf ファイルに分離されています。
</para>

<para>
&fml8; は起動時にそれらのファイルを順番に読みこみ、
最後にＭＬ固有の config.cf を読み込みます。
そして、すべての設定ファイルを読み込んだ後に変数の展開処理を行ないます。
</para>

</sect1>

<!-- ======================================= -->
<sect1>
	<title>
	展開後に変数を代入すると？
	</title>

<para>
$ をふくむ変数に値の代入が行なわれると、
その場では評価されません。
</para>

<para>
次に、値を取り出すメソッド
   <footnote>
   <para>
   perl の tie() 操作
   </para>
   </footnote>
が呼ばれた際に、初めて変数の再展開が行なわれます。
</para>

<para>
たとえば
<screen>
$config->{ key } = '$ml_home_dir/value';
</screen>
という代入処理が行なわれると、次に
<screen>
$config->{ another_key }
</screen>
(キーはなんでもよい)メソッドが呼ばれた際に、
変数群すべてが再評価されます
(たがいに依存関係があるため、すべての変数が評価されなければなりません)。
</para>


<sect2>
	<title>
	内部構造: 変数展開
	</title>

<para>
少し内部構造の話をします。
</para>

<para>
値の代入操作が行なわれると、
まずは %_fml_config に キーと値 の組が保存されます。
これは $dir/$file のような代入した値そのままです。
</para>

<para>
get() メソッドは、
%_fml_config ではなく %_fml_config_result の値を返しています。
%_fml_config_result 中の値は $dir などが展開された後の値で、
/var/spool/ml/elena/file などとなっています。
この変数の値の展開は get() メソッドなりが呼ばれた際に初めて行なわれます。
</para>

</sect2>

</sect1>


<sect1 id="list.variables.by.alphabeticalorder">
	<title>
	変数一覧 (alphabetical order)
	</title>

&var.table.list.variables;

</sect1>


<sect1 id="list.variables.by.class">
	<title>
	変数一覧 (クラス分類)
	</title>

&var.table.class.variables;

</sect1>


<sect1 id="recipes.internal.config.cf">
	<title>
	レシピ’s	
	</title>

<qandaset>

<qandaentry>

<question>
<para>
config.cf 内で使って良い関数はどれですか？
</para>
</question>

<answer>

<para>
つまり、フックで利用可能な関数は何ですか？という設問ですが、
公式には「$curproc オブジェクトが提供するメソッド」となります。
</para>

<para>
たいていのオブジェクトに今あるメソッドは将来も廃止されないと思いますが、
いちおう $curproc オブジェクトが提供するメソッドとしておくのが安心です。
</para>

<para>
注意:
&fml4; の設定ファイル config.ph と異なり &fml8; の config.cf では 
=cut より前は変数を書く場所です。
perl の関数を書く場所ではありません。
=cut の後にはフックつまり perl script を書きます。
</para>

</answer>

</qandaentry>

</qandaset>


</sect1>


</chapter>
