                内部構造や実装の理屈についてなど

------------------------------------------------------------
1	概要
1.1	ML Server Process Overview
1.2	Historical View
1.3	Policy
1.4	機能の概要
1.5	インストール

2	fml の機能についての概要
2.1	Directory 構造
2.2	インストーラ
2.3	ドキュメントについて
2.4	一般ユーザー権限ということ
2.5	ライブラリ・モジュールとダイナミック・ローディング
2.6	設定ファイル (config.ph)
2.7	アクセス制御と自動登録
2.8	ファイル操作: 取り寄せとまとめ送り
2.9	MIME や base64 等の処理 
2.10	リモートでＭＬを管理すること
2.11	.forward
2.12	Listserv/Majordomo
2.13	MTAとの通信 (e.g. sendmail)
2.14	MTAがメールを受けとれないマシンの時
2.15	セキュリティ
2.16	その他の機能

3	Version Up と互換性について
3.1	how to version up
3.2	新しい機能を有効にするには？
3.3	config.phの互換性について
3.4	互換性のためのライブラリ
3.5	FML 1.6 より前からの移行について
3.6	FML 2.0 との互換性 (get コマンド)
3.7	hml 1.6 との互換性

4	設計指針に関するいくつかの考察…
4.1	From: はすべてを認めるべきだろうか？
4.2	ML無限ループのチェックメカニズム
4.3	newsyslog(8)
4.4	Date: == サーバが配送した時間
4.5	Received: を削る
4.6	Return-Receipt-To: も削るべき

5	ファイルをまとめて操作する関数群 (mgetとまとめおくりで使う)
5.1	mget options (help file より)
5.2	mget3 のデフォールトの変更
5.3	mget3 インターフェイス:パターンマッチ戦略
5.4	プログラムのパス
5.5	mget3 の送り返しプロセス
5.6	コマンドで単なるシンタックスエラーの警告をする
5.7	mget の送り返し時のファイルサイズ
5.8	mget で指定できるファイルの最大数
5.9	Mget Format: Unix From 形式
5.10	Mget Format: MIME/MultipartのBNF表現（RFC1521より）
5.11	Mget Format: MIME/Multipartの見本
5.12	Mget Format: RFC934
5.13	Mget Format: RFC1153 digest 
5.14	Mget Format: 1153 のカスタマイズ
5.15	Mget Format: lzh + ish option
5.16	SJIS にファイルを変換して送る （lzh + ish と lhz + uuencode option）

6	FML のプロセス
6.1	ＭＬサーバの動作 (fml と sendmail の役割分担)
6.2	Sendmail -> fml.pl 時の動作
6.3	ライブラリのファイルを探す順番 (fml.pl と ARGV)
6.4	設定ファイルのサーチ順番
6.5	fmlのプロセス(STDINからの読み込みの第一段階)
6.6	fmlのプロセス(第２段階, %Envelopeの処理)
6.7	fml process の lock と signal handling 
6.8	イベント・スケジューラ
6.9	ロックの仕方(flock でない場合)

7	FML 内部におけるデータ構造
7.1	変数名の naming convention
7.2	関数名の Naming Convention
7.3	%Envelope (ハッシュテーブル)
7.4	データ構造の初期化
7.5	ディレクトリ変数
7.6	$TMP_DIR について
7.7	設定ファイル群
7.8	単に便利なためにある変数
7.9	内部で使われている変数を調べるには？

8	FML 設定ファイルのフォーマットと構造
8.1	members ファイルのフォーマットと構造
8.2	actives ファイルのフォーマットと構造
8.3	actives と members の違い
8.4	複数のメンバーリスト、複数の配送リスト
8.5	msendrc ファイルのフォーマットと構造
8.6	パスワードファイルのフォーマットと構造
8.7	FMLインストール後の maintenance と version up に関して

9	Security 
9.1	Security 関係の基本思想
9.2	Security Check Routine
9.3	DNS Spoofing
9.4	Address Spoofing
9.5	SYN Flooding
9.6	Email アドレスの表現とRFC822
9.7	smrsh.c
9.8	access(2) 
9.9	Precedence Priority
9.10	4.4BSD vacation
9.11	File and Directory Permission Default
9.12	Directory Permissions
9.13	sendmail 8.8 における check_* ルールセットについて
9.14	SMTP and Authentication
9.15	&system() function

10	ライブラリ関数
10.1	daemon (libutils.pl)
10.2	Sendmail (libsmtp.pl)
10.3	SendFile (libsmtp.pl)
10.4	NeonSendFile (libsmtp.pl)
10.5	Addr2FQDN              (fml.pl)
10.6	AddressMatch           (fml.pl)
10.7	MailListMemberP        (fml.pl)
10.8	MailListActiveP        (fml.pl)
10.9	Append2                (fml.pl)
10.10	AutoRegist             (libutils.pl)
10.11	ChangeMemberList       (libfml.pl)
10.12	ChangePasswd           (libcrypt.pl)
10.13	CheckMember            (fml.pl)
10.14	CmpPasswd              (libcrypt.pl)
10.15	CmpPasswdInFile        (libcrypt.pl)
10.16	Conv2mailbox           (fml.pl)
10.17	DecodeMimeStrings      (libMIME.pl)
10.18	Flock                  (fml.pl)
10.19	Funlock                (fml.pl)
10.20	GetID                  (libfml.pl)
10.21	GetTime                (fml.pl)
10.22	Lock                   (fml.pl)
10.23	Log                    (fml.pl)
10.24	LogWEnv                (fml.pl)
10.25	Lookup (fml.pl)
10.26	MailListActiveP	(fml.pl)
10.27	MailListMemberP	(fml.pl)
10.28	Mesg                   (fml.pl)
10.29	NewSyslog              (libnewsyslog.pl)
10.30	Notify                 (fml.pl)
10.31	RunHooks               (fml.pl)
10.32	ExecNewProcess		(fml.pl)
10.33	SecureP                (fml.pl)
10.34	SendBackInOrder     (libfop.pl)
10.35	SocketInit             (libsmtp.pl)
10.36	TurnOverW0             (libnewsyslog.pl)
10.37	Unlock                 (fml.pl)
10.38	Warn                   (fml.pl)
10.39	WholeMail              (fml.pl)
10.40	eval                   (fml.pl)
10.41	ipc                    (libutils.pl)
10.42	system                 (libutils.pl)

11	Porting to other Operationg Systems
11.1	Micro$oft NT 4.0
11.2	sys/ Directory

Appendix A	変数名や関数名の名付け方の慣習について
Appendix A.1	関数名

Appendix B	some debug information
Appendix B.1	ロードしていく様子の例 (配送の場合)
------------------------------------------------------------


1	概要

＊＊＊ まだまだ、整理途上です。 ＊＊＊

ここは 内部構造について、fml 開発者向け情報の集積地です。旧 
fml/doc/smm/ の一番濃い部分がここに移されてきたと思ってもいいです。

-- ＭＬサーバの設計ポリシーとはなんだろうか…

   ・日々の routine work をいかに自動処理化できるか？

   ・可能な限り user および ＭＬ管理者 にとっての自由度をあげる

   ・デフォールトは単に配送とユーザ用のコマンド(help や記事の取り
     寄せ、配送先の変更/停止等)

   ・しかしそれ以外の様々な機能もひととおり準備されていると便利
     これらの高度な設定は管理者が明示的に設定しなければならない。
     というのは管理者は何をしているのか知っているべきだし、
     何をしているかの把握はセキュリティ的にも望ましい。

    ………

1.1	ML Server Process Overview

ＭＬサーバは本質的にフィルタリングをするものです。ＭＬ宛のメールが来た
ら配送プログラム(MTA)から起動されいろいろな処理をした後、配送するべき
(MLの)メンバーリストを配送プログラムへ渡します。後は配送プログラムが配
送を行ないます。つまり配送はＭＬサーバの役目ではありません。

[図]

あるホスト                                    ＭＬサーバのマシン

ＭＬのメンバーからのメール

   |
   V
  MTA (e.g. sendmail)  ------------------>     MTA (e.g. sendmail)

                                                |  kick off the ML server
                                                V

                                            ＭＬサーバ(ドライバともいう)

                                                |  
                                                V

                                    MTA (e.g. sendmail)  配送プロセス

                                             |  |  |  |  |  |
                                             V  V  V  V  V  V

                                             ＭＬのメンバー

配送プロセスは上図のように動きます。ＭＬサーバが普通のメールではなくあ
る命令(ＭＬを辞める、過去の記事を読むなど)を含んだメールをうけた場合は、
それ(コマンド)を実行してその結果をリクエストした人へ送り返します。

上図からわかるとおりＭＬ宛のメールが来た時だけＭＬサーバは起動されます。
つまり"不定期"にです。そのためリアルタイムにＭＬの記事(メール)を読みた
くない人、例えば3時間に一度過去3時間のメールをまとめて読む「まとめ送り」
の場合は"定期的に"まとめ送り(digest 2)を実行するプログラムが起動さ
れる必要があります。FMLは定期的に起動しなければならないプログラム群は
cronというオペレーティングシステムが提供する機能を使っています。
See also: digest 2.17 
See also: digest 2.17 

1.2	Historical View

FML は Mailing List Server の package (Perl Scripts package) で、
僕が壱から Full Scratch したものです。
＃おまけCDROMつき雑誌等にある「…の改良」の記述は間違った推測なのです

これからＭＬをはじめる方にはそのままＭＬサーバをカスタマイズして使いた
いとおもっている方には改造の PLATFORM として利用してもらうことを想定し
ています。

最初の発端は(フリーソフトの例にもれず)

	bug っているサーバ、
	機能の足りないサーバ、
	直すより自分で書いた方が早い

単にそういう話でした(ま、よくある話ですね:-)。

歴史的に hml 1.6 を一時期使っていて、その設定ファイルをコンバートする
のは面倒でした。そのためhml 1.6 を emulation するように設定することも
できます。

1.3	Policy

『Mailing List は Private Communication を便利にするツール(Filter) 』
という観点を重視しているため、デフォールトではメンバーのみが投稿やコマ
ンドを使える という考え方を尊重しています。

プログラムを使う以上は日々の routine work をいかに自動処理化できるか？
使いやすくできるか？が重要です。そのためにもユーザにみえるインターフェ
イスなどは様々なインターフェイスが提供されて好きなものを使うのが理想で
しょう。デフォールトは

	『投稿用のアドレス』と『コマンド用のアドレス』があり、
	それらのアドレスでMTA (e.g. sendmail)が受けて fml.pl を起動する

という形態です。しかし『可能な限り user および ＭＬ管理者 にとっての自
由度をあげる(簡単に設定できる自由度をできるだけ確保するべき)』という理
想も追求したいところです。その結果として

   ・設定ファイルには sendmail.cf なみに様々な変数が定義されている

のを筆頭に

   ・コマンド用のアドレスは listserv(majordomo) スタイルでも可能

   ・ sendmail が動いていなくても POP3 を使ってＭＬを実行する

等様々なインターフェイスがパッケージ中に収録されています。

ＭＬサーバというものは一番肝心な部分はかなり簡単なのですが、実際にはさ
まざまな例外処理が発生します。それをいかに封じ込めるかをノウハウという
わけです。またユーザー環境による違いを吸収するためにさまざまな関数をサ
ポートする必要がありました。例えば ish, lha サポートはその一例といえる
でしょう。

一方セキュリティ的には

   ・必要なことはしても、できるだけ何もしない
   ・機能の増加は簡単な configuration で、しかし明示的に指定しない限り
     よきにはからって動くべきではない

といえます。これが

   ある機能をONにする変数はあるが、明示的に指定しない限りONにはしない
   つまりデフォールトでは様々な機能はOFFにされている。	

ということの背景です。

多くの変数があるのは、簡単にある変数の値を変えるだけで挙動が変えられる
ようにするためです。また、それにより設定を操作するためのインターフェイ
スを割と簡単に書くことができます。例えば makefml です。makefml を使っ
てのインストールや簡単な設定の変更が可能です(ある程度以上複雑なことは
手でやって下さい)。また頑張ればWWWインターフェイスもすぐ書けるでしょう
(でも誰も作らないな:-)。

各種機能はそれぞれの目的に応じて選んでみて下さい。例えば『あるＭＬのロー
カルな再配送』のような場合はコマンド機能を落して使うべきでしょう。

例: ip-connection を受けるアドレス (include ファイルを呼び出すアドレス)
に使う時は、makefml config listname で 配送モード指定を「誰でもPOST可
能」にする。

	$PERMIT_POST_FROM = "anyone";

1.4	機能の概要

ＭＬサーバはおおまかに
				設定ファイル(config.ph)の変数
	_____________________________________________________

	配送用のアドレス	$MAIL_LIST	
	コマンド用のアドレス	$CONTROL_ADDRESS

からなります。特別な場合には(歴史的理由により) hml 1.6 (正確にはその元
祖の shell script) というサーバを Emulate します。特別な場合とは 

	配送用のアドレス==コマンド用のアドレス
	($MAIL_LIST == $CONTROL_ADDRESS)

に相当します。

ＭＬサーバの現在の代表的な機能は以下のようなものです。

   ○ 配送用のアドレスとコマンド用のアドレス 
	-- Chapter how_to_subscribe 6.1

	それぞれについてアクセス制御や自動登録の設定
	なお特別な場合「配送用のアドレス==コマンド用のアドレス」は hml 1.6

   ○ 様々な自動登録方式
	-- Chapter how_to_subscribe 4

	前述のどのアドレスで？ x 4種類 x 各カスタマイズ変数…

   ○ unsubscribe confirmation

	confirmation を bye/unsubscribe コマンドでも使用可能に

   ○ リモートメインテナンス/リモート管理
	-- Chapter remote_control 4

	PGP, パスワード認証等の選択
	-- Chapter encryption 4

   ○ 様々なヘッダカスタマイズ
	-- Chapter header_rewrite 5

   ○ セキュリティ: 内蔵トラフィックモニタ (e.g. メール爆弾対策)
	-- Chapter resource_control 2

	例: トラフィックがある程度以上になると
	ＭＬはメールを自動的に受け付けなくなる

   ○ セキュリティ: フィルタリングコード (e.g. SPAM 対策)
	-- Chapter filter 4.1

	ヘッダの各フィールドごとのフィルタリングコード

   ○ 様々なコマンド
	-- Chapter 5

	ファイル取り寄せのコマンド mget コマンドのいろいろなファイル形
	式のサポート

   ○ まとめおくり
	-- Chapter digest 2

   ○ SMTP配送方式(リレー)
	-- Chapter smtp 3.1

   ○ その他(MIME処理等)
	-- Chapter Japanese 2

   ○ ＭＬに投稿された記事をHTML 4.0形式で作成する。thread化もする。
	-- Chapter html_convert 1.1 html_convert 1

   ○ 記事のアーカイブ、Expire等
	-- Chapter daily 3 daily 5

   ○ 複数のコマンドインターフェイス (listserv や majordomo style)
	みかけがあたかも listserv のようなコマンドの送り方を可能にする
	-- Chapter utility_programs 3

必要に応じて設定ファイルで機能の追加・削減を行うことができます。
簡単なものは makefml で可能です。

1.5	インストール

とりあえず細かいチューニングを行なわなくてよいなら

	make install

ことで、インストールをします。ML の作成は

	perl makefml newml ＭＬの名前

で何個でも作れます。説明は INSTALL というファイルを見て下さい。

2	fml の機能についての概要

注意: インストールやＭＬの作成の仕方についての詳細は INSTALL.jp という
ファイルを読んで下さい。

2.1	Directory 構造

基本的に directory は2箇所からなります。インストール時に makefml で指
定できます。インストール方法の詳細はINSTALLというファイルを参照。

	1 $EXEC_DIR (と makefml でいっている) 
	  実行ファイルとライブラリ群 (e.g. /usr/local/fml)

	2 $ML_DIR (e.g. /var/spool/ml)
	  各ＭＬ群が /var/spool/ml/ に作られる

	   /var/spool/ml/elena/		(elena ML)
	   /var/spool/ml/mirei/		(mirei ML)
	   /var/spool/ml/Freekick/	(Freekick ML)
	   /var/spool/ml/sakura/	(sakura ML)
	   /var/spool/ml/tomoyo/	(tomoyo ML)
	   /var/spool/ml/kerochan/	(kerochan ML)
	   ...

elena ML 関係の全てのファイルは /var/spool/ml/elena/ 以下に作られます。
設定ファイル(config.ph)や記事のスプールも同様です。複数のＭＬを作成す
ると /var/spool/ml/ 以下に並びます。

2.2	インストーラ

対話的処理をする makefml という簡単なインターフェイス(CUI)がついてきま
す。これがインストールやＭＬの作成簡単な設定の変更を可能にしています。
詳しくは INSTALL.jp を参照

初心者には最初は何をどういじってインストールするのかは良くわからないも
のです。とりあえず簡単なものはこれでできるはずです。詳細については 
INSTALL.jp というファイルを見て下さい。

『ある動作をするか？否か？』については config.ph という設定ファイルで
操作することができます。アーカイブやスプール、help ファイルの場所 や
『tar ish lha のような system のコマンド』のようなものもすべて hard
coding ではなく user が外部から制御できる変数として定義されています。
変数リストについて興味があれば cf/MANIFEST を見るとわかります。

2.3	ドキュメントについて

PLAIN TEXT 版はパッケージ中の doc/ にあらかじめ用意されています。README
や INSTALLマニュアル の HTML 版も ぱっけーじ/doc/html/ の下に用意され
ています。

ドキュメントの最新版は

	http://www.fml.org/fml/

にあります。

2.4	一般ユーザー権限ということ

特別なユーザー 例えば daemon 等で動かすのはセキュリティ上好ましくあり
ません。よって一般ユーザー、できればＭＬ用の特別なユーザーを用意し、そ
のユーザの権限でFMLを動かすのが望まれます。通常FMLプロセスのオーナー
(ユーザー)は makefml で作られる include というファイルの所有者です。
また FML は実装上 Trusted User 等を気にする必要はないので daemon で動
かす必要もありません。

少しメカニズムの話をするとMTA (e.g. sendmail) はユーザー権限で動かすた
めに setuid() を行ない、そのユーザーとして fml.pl を起動します。POSIX 
準拠 OSは setuid() をちゃんと行なえる user は root に限られます。これ
はこれで正しい選択だし、ターゲットの 4.4BSD もそういう実装をとっていま
す。そのためMTAから setuid() をしてfml.plを動かすプログラムを走らせた
りはせずにその辺はMTAにまかせています。

sendmail 等がうまく setuid() を実行できない場合 4.3 BSD では fml.c を 
compile して使えば良いでしょう。makefml でインストールしていれば 
makefml が作った Makefile を使うと

	(shell prompt)% make fml

で fml および fml-ctl という実行ファイルが生成され、setuid されます。
fml は投稿用アドレス、fml-ctl はコマンド用アドレスに使います。

4.3BSD では一般ユーザーに setuid() されたこの状態で setuid() が実行で
きます。POSIX 準拠等OSでは ＊非常に危ないですが＊ この fml を root 権
限に setuid しなければなりません。fml, fml-ctl をどこにおいて使うべき
か？について自信がない場合あなたのサイトもしくはそのマシンの管理者によ
く相談して下さい。

2.5	ライブラリ・モジュールとダイナミック・ローディング

モジュールにすることにより

	マスターコードの保守
	自分だけのモジュールを独立に保守

することが容易になります。モジュールはすべて lib"module-name".pl とい
うファイル名です。

もともとは SMTP部分の独立保守と 常時使うわけではないコマンド部分を切り
離すことを目的としたモジュール化でしたが、現在では必要に応じてダイナミッ
クローディングされる様々なライブラリが提供されています。ファイルは一杯
ありますが常に使われるのはそのうちの2、3個くらいです。後は週に一度とか
明示的に設定がされた場合のみにしか使われないようなものです。

モジュールはインターフェイス仕様さえ不変なら独立に保守できます。
contribution され独立に保守されているコードも同様にライブラリに入って
います。例えば libtraffic.pl は

	libfml.pl の関数呼びだしインターフェイスに合わせれば、後は
	すべて user defined で作れる

というよい例です。
＃ぼくは中身についてタッチしていません。fml master code tree とは独立
＃に保守されています（感謝）

FML はこのライブラリ群が本体で、その動きを設定ファイル(config.ph)でカ
スタマイズするようになっています。そのためライブラリ・モジュールは一箇
所にまとめておくと『ひとつのfmlで複数のＭＬを扱うように拡張』等も容易
になり、また version up も楽です。makefml でインストールする場合はそう
いう形態になります。

例:
	ライブラリは /usr/local/fml の下に全部入れる
	ＭＬ群は /var/spool/ml/each-ml/
	   (e.g. /var/spool/ml/each-ml/config.ph )

ＭＬを配送ではなく特定の目的のサーバのみを dynamic loading して
『特定の目的のサーバ』にすることも簡単にできます。
＃config.ph で特定のファイル名を $LOAD_LIBRARY に設定する

これにより、

	コマンド 専用サーバ
	ftp 用サーバ
	ftpmail  専用サーバ 
	メールで request をうけてURLの中身を返すサーバ

等の専用サーバに設定することもできます。	

2.6	設定ファイル (config.ph)

できるだけソースコードを直接いじらなくてもたくさんの制御変数とフックで
カスタマイズできるようになっています。カスタマイズ可能な変数は 
config.ph 中に簡単な説明とともに書いてあるのでこれを変更することで行な
います。基本的なものについては makefml で変更ができます。

2.7	アクセス制御と自動登録
See also: how_to_subscribe 4 

前述のとおりデフォールトは来たメールの From: を見てメンバーチェックを
します。FML 2.1 以降では投稿とコマンドそれぞれについて以下の

	・誰からの投稿を許すか？
		だれでもOK			anyone
		登録されているメンバーだけ	members_only
		モデレーターだけ		moderator (how_to_subscribe 5)

	・もし、登録されているメンバー以外から来た場合にはどうするか？
		許否				reject
		自動登録			auto_regist
		無視(管理者へ報告だけする)	ignore

を設定できます。デフォールトはいずれも

	メンバーのみ(members_only) 投稿/コマンドの使用 が可能
	もしメンバー以外から来たら許否(reject)

です。自動登録は"投稿がメンバーだけ"(members_only)の場合に

	もしメンバー以外から来たら自動登録 → auto_regist へ変更

することで行ないます。自動登録のタイプは4種類あります。

2.8	ファイル操作: 取り寄せとまとめ送り
See also: 5 digest 2 

get, mget, matome 等のコマンドにはオプションで tar.gz で固めてとか 
MIME/Multipart 形で記事をまとめて送り返して欲しい等の変更ができます。
mget と まとめおくりでの User interface は次のようなものが取り揃えられ
ています。mget コマンド毎に指定を変えることができます。

	PLAIN TEST 
		UNIX FROM
		RFC934	
		RFC1153
		MIME/Multipart

	COMPRESSED FILE
		gzip UNIX FROM file
		tar + gzip
		uuencode

	   (日本使用)
		Lha + Ish 	(自動SJIS変換可)
		Lha + uuencode 	(自動SJIS変換可)

mget で取り寄せられるのはデフォールトは $SPOOL_DIR (default "spool") 
ですが対象は標準のＭＬの記事スプール以外にも @ARCHIVE_DIR に指定するこ
とで増やすことができます。

ファイル操作の応用編としてユーザーが put も get できるように拡張された
コマンドも実装しています(library コマンド)。ただしデフォールトでは、
put するファイル名はセキュリティ上選べません。ファイル名を明示的に指定
する場合は安全のため管理者が変更するべきです。
See also: command 5.1 

2.9	MIME や base64 等の処理 
See also: html_convert 1 

メール本文は基本的に素通しです。Subject のMIMEは decode してサマリーを
作ります(2.2ではデフォールト)。またHTMLでは base64 の画像等の変換処理
を下請けのプログラムに渡して行ないます。つまりメール中の gif ファイル
を変換してメールの記事の html を生成します。

2.10	リモートでＭＬを管理すること
See also: remote_control 4 
See also: encryption 4 

デフォールトではできません。設定ファイルで

	$REMOTE_ADMINISTRATION  = 1;

を設定するとできるようになります(makefmlでも設定できます)。
管理者として登録された人に対し

	From: 行での認証
	管理者一人ごとのパスワード	(秘密鍵暗合)
	PGPベースでの認証		(公開鍵暗合)
See also: encryption 4 

の組合せで認証をします。デフォールトは

	From: 行での認証
	管理者一人ごとのパスワード	(秘密鍵暗合)

です。どうせやるなら PGPベースが推奨です:)

FML 1.0 で『管理者が本当に操作しているかどうか?という点に関して保証で
きない』という理由ではずしたリモート管理(アドミンコマンド)を再実装し、
サポートします。保証できないという意味は From: での認証は簡単に偽造で
きるからです。

多くの場合ＭＬではリモート操作はパスワードで認証しています。しかしなが
ら、メールの中では平文パスワードを書く必要がありますし、ひとりの管理者
のパスワードは毎回同じで使い捨てではありません(時系列に沿って)。よって、
間違ってメールが読まれた場合を考えると危険なわけです。

PGPベースではこの心配はありません(もちろんあるメール全体を読まれていれ
ばそのメールと全く同じ内容を実行だけは可能なはずですが)。

FMLのリモート管理モードではパスワードは各管理者ごとに設定できます。
PGPの場合は管理者一人一人の public key を入れることになります。

管理者全体で一つの共通パスワードというようなださい実装はしません。これ
は普通の UNIX の パスワードシステム のミニチュア版です。サーバ側では 
$DIR/etc/passwd に 管理者ごとにパスワードを保存しています。 保証の度合
が上がったわけではありませんが、パスワードは crypt し保存しています。
一応かつての UNIX 程度の保証はされます。パスワードの保存を MD5 にする
こともできます。PGPではMLごとに $DIR/etc/pgp/ 以下に keyringを作りMLご
とに別のPGPPATHを用います。
See also: encryption 4 

2.11	.forward
See also: utility_programs 4 

通常 include ファイルを設定するのは /etc/aliases ですが .forward は本
質的に同じものです。もっとも .forward の場合ユーザー名以外のものを使う
ことはできないわけですが。だから include は .forward に設定すれば同じ
です。詳細は utility_programs 4

2.12	Listserv/Majordomo
See also: utility_programs 3 

   Listserv 互換用インターフェイス 	libexec/fmlserv.pl

fmlserv.pl を呼ぶようにした場合 コマンドは

	コマンド ＭＬ名前 オプション

になります。ようは Listserv 形式のしんたっくすで fml のコマンドを使え
るようにしたインターフェイスです。

	listserv:  fmlserv
	majordomo: fmlserv
	fmlserv: :include:/var/spool/ml/include/fmlserv

のようにしても大丈夫です。

2.13	MTAとの通信 (e.g. sendmail)

FMLは sendmail 等の SMTP配信エージェントと自力で通信します。

	$Envelope{'mci:mailer'} = 'ipc'; (default)

の場合 $HOST で指定されているマシンにSMTP でコネクションを張り配送をま
かせます。$HOSTのデフォールトは自分のマシンで、つまり自分のマシンで走っ
ているMTAと通信します。

	$Envelope{'mci:mailer'} = 'prog';

の場合 $SENDMAIL という変数のプログラムを起動してそれに配送をさせるこ
ともできます。

SMTP を理解してくれるなら sendmail である必要もないし配送用に使える
SMTPサーバ があれば動きます。それは必ずしも自分のマシンで sendmail が
走っている必要はありません。各サイトで走っているSMTPを理解してくれる配
送プログラムがあればよいです。sendmail が走っているマシンが一つもなけ
れば sendmail を起動するように 'prog' を指定すればよいです。

2.14	MTAがメールを受けとれないマシンの時
See also: utility_programs 5 

逆にどうやってメールを受けとるかという問題があります。通常 SMTP を理解
する受けとるサーバが走っていて、メールを受けとり fml.pl へ渡します。例
えば一定時間間隔で POP をかけてＭＬを動かし、配送はサイトの SMTP サー
バにやらせることでＭＬを実行するこは可能です。

2.15	セキュリティ

ＭＬのトラフィックをモニターして一気にメールが送られてきたらメール爆弾
と判定してrejectするとかヘッダやメール本文の特定のパターンをフィルタリ
ングする機能もあります。詳しくは 9

2.16	その他の機能

ロックは flock によるロック処理をデフォールトにしています。が flock() 
が動かない場合 UNIX V7 以来の link() によるロックを使います。

リレーサーバを設定できます。例えば、関東方面、関西方面にこねがあって、
マシンが調達できる場合、関東方面のメールを一回そのマシンに送ることで関
東方面へおくるメールを一つのメールでいっきにおくって、配送はそのリレー
先にまかすことで、配送を高速化できます。
注意: 現代のMTAでは対SPAM設定が普通ですからやるのであればちゃんと折衝
しましょう。

プロバイダ等でDISKに制限があったりする場合は、古い記事は消したいとおも
いますがそのための自動圧縮や Expire の機能をサポートします。

newsyslog(8) 的機能をサポートしています。古いログは自動的に

	members -> var/log/members.0 

のように変換し保存するようにしています。デフォールトでは members ファ
イルや まとめおくりのログに対して newsyslog を実行しています。
＃参照: % man newsyslog

一つのマシン上にある ＭＬ間のクロスポスト の場合、
複数のＭＬに入っている人には一通しか送らないようにします。
＃サイトにまたがる場合はデータのシンクロが必要なため実験段階です

おまけ機能として、スタートレックの宇宙歴をサポート(笑)します。
contrib/Utilities に宇宙歴をつけるmh, mh-e user interface つき:-)です。
See also: header_rewrite 3.14 utility_programs 6.26 

3	Version Up と互換性について

3.1	how to version up

makefml を使ってインストールしてもらうのが確実です。makefml の使い方に
ついては INSTALL.jp というファイルを見て下さい。

3.2	新しい機能を有効にするには？

通常新しい機能・オプションは明示的に指定しない限り動きません。
設定変更は config.ph で行ないます。詳しくは INSTALL.jp を参照。

version up して以前になかった機能を使うなら必要な変数を op.jp などから
探し設定を付け加えるます。すでにあるが使われていない機能を新たにONにす
るなら config.ph をサーチして値を1にするとか適当な設定を書くなどします。

基本的な変数であれば makefml で設定できます。makefml との共存やメイン
テナンスを考え $DIR/cf をいじり config.ph を再生成するようにするのが前
提となっています。"makefml config" を使わないなら cf をいじらずに 
config.ph を常に手動編集することになります。

3.3	config.phの互換性について

FML では config.ph という設定ファイルが振舞いを決めます。
config.ph にも version という概念があります。

	$CFVersion

という変数で指定されています。現在の version は 3.x です。version が異
なる場合、ほとんどの変数について自動的に補正が加えられるため昔作った 
config.ph をそのまま使っても大丈夫なようになっています。

config.ph でちょっと複雑な HOOK をかけている場合はちょっと注意がいるで
しょう。互換性のために実体は別でもその関数名が残っていることは多いです
が、HOOKで使う関数や変数全部が今でもサポートされているとは限らないから
です。

できるだけ互換性を保つように作られていますが

    config.ph の $CFVersion が 3

でなおかつ

   『$MAIL_LIST と $CONTROL_ADDRESS が違う場合の $MAIL_LIST の挙動』

の時は従来と異なり『配送専用』です。ここだけは互換性がありません。しか
し

	$MAIL_LIST と $CONTROL_ADDRESS が同じ場合は
	昔と同じで配送用のアドレス $MAIL_LIST で
	コマンド(# command の形)を受け付けます。

従来 $MAIL_LIST != $CONTROL_ADDRESS の場合にヘッダやHELP等では「コマン
ドは $CONTROL_ADDRESS へ送ってね」と書いてあるにも関わらず $MAIL_LIST 
でもコマンドは受けられたという変な挙動がありました。これを互換性と解釈
するかバグと解釈するかは微妙ですが、FML 2.1 以降はアクセス制御ルールの
導入時に上記の解釈になりました。

______________________________________________________
[比較表]

	elena		配送専用
	elena-ctl	コマンドだけ

になります。2.1 リリース以前(2.1 Gamma series)では 

	elena		配送もコマンドも処理する
	elena-ctl	コマンドだけ

のように振舞いました。elena でのコマンドの「配送とコマンドの切り分け」
はメール本文が"# command"であるか？否か？で決めています。

2.1 以降でも配送用とコマンド用のアドレスが同じ場合は

	elena		配送もコマンドも処理する

になります。この場合「コマンドなのか？否か？はメール本文が"# command"
であるか？否か？」で決まります。これがもともとの hml 1.6 互換のスタイ
ルです。
______________________________________________________

3.4	互換性のためのライブラリ

cf/config という生成コマンドで作るようになった時 $CFVersion = 2; とい
う version が与えられました。さらに、それ以前の手動編集のみだった時代
の config.ph を使っている場合($CFVersionがない時代)は 1 と定義されてい
ます。

	$COMPAT_CF1 = 1;

がセットされているか $CFVersion が2より小さい場合は自動的に

	libcompat_cf1.pl

が dynamic loading されます。また 3 以下と判定された場合は

	libcompat_cf2.pl

が自動的にローディングされます。

3.5	FML 1.6 より前からの移行について

1.6では、基本的なデータ構造を call by reference 用に書き直したので、
いままでの SMTP_OPEN_HOOK 等の カスタマイズはそのままでは反映されません。
libcompat.pl にBackward compatibility のためのコードがあります。
昔の設定を変えたくないなら、config.ph に 

	$COMPAT_FML15 = 1; 

と書くと複雑なフックをしかけていない限り compatible にできます。
コードの都合上どうしても実現できないカスタマイズもありえます_o_

昔できたことは今の実装でも必ずできるのでこのドキュメントを参照してみて
下さい。

3.6	FML 2.0 との互換性 (get コマンド)

	$COMPAT_FML20 = 1;

これに関係する機能は

   現在の get コマンドは resend ですが、これを昔のもの(2.0以前)に戻す。

くらいです。なお前述の $MAIL_LIST の非互換性は 2.1 gamma → 2.1 delta 
の時に導入されました。
See also: 3.3 

3.7	hml 1.6 との互換性

   0	members や log file 等はそのままでよい

   1 	fml をインストールし

   2 	makefml か手で config.ph で
	$MAIL_LIST と $CONTROL_ADDRESS の内容を同じにする。 

これで同じになります。whois などの機能については似たような機能はあって
も同じものはないので御了承下さい。基本的に移行は簡単でもすべての機能の
上位互換なわけではありません(security holeもあるのでそんな実装はするつ
もりはなかった)。

4	設計指針に関するいくつかの考察…

4.1	From: はすべてを認めるべきだろうか？

現在は $REJECT_ADDR で定義されたアドレス群を From: に含むものはエラー
として管理者へフォワードされます。それは個人を代表しているとみなされな
いアドレスにたいしてです。というのはＭＬとは個人と個人を結び付けるもの
だと思われるからです。現在は

    $REJECT_ADDR  = 'root|postmaster|MAILER-DAEMON|msgs|nobody';
    $REJECT_ADDR .= '|majordomo|listserv|listproc';

のように設定されています。From:がこれらのアドレスだった場合管理者へフォ
ワードし伺いを立てます。そこから後はＭＬ管理者の判断でしょう。

この他にも uudecode や sysdiag(苦笑) のような attack で出てきそうなア
ドレスもありますが、まぁまず使ってないでしょう。果たしてこれは増やすべ
きなのか、減らすべきなのか？私見としては、もっと増やすべきではないだろ
うかと思うのですが…

正規表現でマッチした Email アドレスをはじく機能もあります。
$REJECT_ADDR_LIST 中に正規表現を定義します。デフォールトは(CF に合わせ
て) spamlist というファイルです。
See also: filter 2.13 
See also: filter 2.13 

4.2	ML無限ループのチェックメカニズム
See also: 7.7 

デフォールトは $CHECK_MESSAGE_ID がセットされています。この時は
「Message-ID: フィールドはメールそれぞれについて時空全体で unique であ
る」という定義を利用したループチェックを行ないます。

これ以外にもチェックはしていますが、理論上はこの uniqueness がもっとも
美しいでしょうね。

4.3	newsyslog(8)

/usr/bin/newsyslog に対応するものとして、libnewsyslog.pl が実装されて
います。昔の /etc/daily 等では

	...
	rename log.0 log.1
	rename log log.0
	...

とやっていたログファイルの整理を行なうプログラムです。NetBSD では、も
ともと MITの Athena Project で作られたプログラムが使われています。
fml.pl がnewsyslog を使って処理するデフォールトのファイル群は
@NEWSYSLOG_FILES で次のファイルに定められています。

    @NEWSYSLOG_FILES = 
	("$MSEND_RC.bak", "$MEMBER_LIST.bak", "$ACTIVE_LIST.bak");

つまりまとめおくり、配送・認証リスト等の変更があった時にできるバックアッ
プファイルです。これは日曜の朝 msend.pl (まとめおくりのプログラム)が実
行しています。まとめ送りをしていないなら実行されません。
まとめ送りをしていないならなんらかの形で別途動かす必要があります。

また関数コール自体(&NewSyslog)の引数(配列)は整理したいファイル群です。
変数 $NEWSYSLOG_MAX は「整理するのは何個までか？」を決めます。デフォー
ルトは４で、つまり

	log.4 log.3 ... log.0 log 

まで順番にまわって保存・整理されます。@NEWSYSLOG_FILES のログファイル
は msend が日曜の朝 newsyslog をかけます。

4.4	Date: == サーバが配送した時間

Date: の付け方は $DATE_TYPE で変更できます。詳しくは header_rewrite 3.5。

元々の理念は、サーバをどう考えるか？という観点で

1	サーバが単にリレーしてるだけ (passive?)

なのか

2	サーバまでの通信路はＯＫでした、はい。
	じゃ今からサーバ→メンバーへ配送するね(active?)

最初のデザイン当時 2 を重視したと。で、Posted: がサーバまでの配送の最
低限の pointer として残して、Date: にはサーバ→メンバー配送のための情
報としてサーバの localtime() をつけたと。そんな歴史的背景がありますね
＃まぁ当時からUUCPは除いて大抵２つはほとんど同じだったですけどね

Date: と Posted: の時間差でネットワークのDELAY情報が分かるのは副次的効
果です。

その他の副産物として時間順ソートをするだけでＭＬの記事を追うことができ
ます。つまりサーバが受けとった順ですね。
＃配送は途中のパスすべてに依存するのでメールを出した元の時間が
＃情報の順番とは限らないからです。
＃ See fml-support's ML Count: 01816, 01821 for the discussion

4.5	Received: を削る
See also: header_rewrite 3.4 

4.6	Return-Receipt-To: も削るべき

配送したメンバー全員からメールが返ってくるから削るです。

もちろん本来はヘッダの意味を考えてメールを書かない”そのメールを出した
人”が悪いのはいうまでもありまん。

5	ファイルをまとめて操作する関数群 (mgetとまとめおくりで使う)

5.1	mget options (help file より)

mgetは『そのコマンドごとに』『まとめおくりはユーザーごとに』送り方が指
定できます。以下 help ファイルより抜粋

mget range 	[モード]	[時間間隔]
			ファイルをまとめて送り返す
			スプールの記事や、
			(もしあれば)アーカイブにあるファイル
   引数:
	range		範囲を指定
			1-10,12,15-100 1,2,10
			first first:10 last:30 100-last(mh的 Syntax)
	モード		gz tgz ish rfc934 b rfc1153 d unpack uf(default=tgz)
	時間間隔	送り返すメールが複数の時の間隔(default=300)	

   モード:
		オプションなしは tar+gzip で spool.tar.gz
	tgz	同上
	uf	PLAINTEXT(UNIX FROM)
	gz	GZIP(UNIX FROM)
	b	RFC934 format 	PLAINTEXT(mh-burst)
	rfc934	
	ish	lha + ish 
	lhaish
	i
	li
	lu	lha + uuencode
	lhauu
	unpack	PLAINTEXT(UNIX FROM)
	uu	UUENCODE
	d	RFC1153 format 	PLAINTEXT
	rfc1153	RFC1153 format 	PLAINTEXT

以下ではこれらの

	複数のファイルを一辺に取り扱う方法
	そのフォーマットについての少し細かい点

に関して記述します。

5.2	mget3 のデフォールトの変更

○ 複数のファイルを一つにする時のまとめ方のデフォールト
$MGET_MODE_DEFAULT can change the default file format "mget" command
sends back. The default format is "tgz" on UNIX, 'mp' on Windows NT4.

libsendfile.pl では

    local($mode) = $MGET_MODE_DEFAULT || 'tgz'; # default

のようになっています。オプションで明示的な指定がない場合は

	tar して gzip をかけたフォーマット(binary)
	そして uuencode して送られます。

で送り返されます。このデフォールトは $MGET_MODE_DEFAULT で変更できます。
定義して意味のある変数は 上述のmgetのオプションと同じと思って構いませ
ん。正確には(libfop.pl中で定義されている) %_fp というハッシュテーブル
のKEY(2番目の引数のフィールド)です。

	uf
	rfc934
	rfc1153
	mp
	gz
	tgz
	lhaish
	lhauu
	uu

○ アーカイブ(var/archive や library コマンドや…)のencodingのデフォールト

spool とは別にＭＬのアーカイブがある場合がありえます。例えば

	電話番号簿(TEXT)
	100個ずつにまとめたスプールの記事(BINARY)

このアーカイブを取り寄せる時のデフォールトは

	テキスト	$MGET_TEXT_MODE_DEFAULT
			(デフォールトは 'mp' MIME/Multipart)

	バイナリ	$MGET_BIN_MODE_DEFAULT
			(デフォールトは 'uu' uuencode された状態); 

    	$mode = -T $opt ? 
    	    ($MGET_TEXT_MODE_DEFAULT || 'mp'): 
    	($MGET_BIN_MODE_DEFAULT || 'uu'); 

○	Subject の設定 

	$MGET_SUBJECT_TEMPLATE

という変数をテンプレートとして用いています。これを元にいくつかの入れ替
えをおこなって subject を生成しています。
これは

   result for mget _DOC_MODE_ _PART_ _ML_FN_

のように定義されている場合

	   _DOC_MODE_   <=>    [last:10 tar + gzip]
	   _PART_       <=>    (1/4)
	   _ML_FN_      <=>    $ML_FN (here is "(Elena Lolobrigita ML)") 

という置換えが行なわれ、最終的に

   Subject: result for mget [last:3 tar + gzip] (1/1) (Elena Lolobrigita ML)

という形で mget の result が送り返されます。よってこの変数を適当に削る
なりすれば subject をカスタマイズできます。

これにより $NOT_SHOW_DOCMODE (CFVersion 2) と $DEFAULT_MGET_SUBJECT は 
obsolete になりました。

5.3	mget3 インターフェイス:パターンマッチ戦略

この時点で flock もはずれて、最後の最後あとは、&Notify だけが残ってい
る

	MH風展開を実行
		e.g. 1,last:30 -> 1,70-100

	if V2 フォーマットでTRY
		e.g.
		spool/PLAIN-ARTICLE
		archive/100.tar.gz 
		等を探索
		return

	elsif ではそのパターンはアーカイブ？
		ほとんど Exact にアーカイブ内を探索
		return

	elsif V1 format 探索 (廃止)
		なら、実行
		return

	else
		NO MATCH or V1 FORMAT ERROR

5.4	プログラムのパス
See also: 6.4 7.4 

ファイル操作ではいくつか下請けのプログラムを呼ぶことがあります。これら
は makefml が自動的に検出し、設定するはずです。でも一応確認はして下さ
い。自分でチェックしながら config.ph に書くのは管理者として望ましい態
度です。site_init.ph もしくは sitedef.ph 等で一回ちゃんと記述してあと
はほっておくというのもよい手です。

現在ファイル操作関係で自動的に検出し設定されるのは次のコマンドです。 

	変数名				設定例

	$TAR                           = "/usr/bin/tar cf -";
	$UUENCODE                      = "/usr/bin/uuencode";
	$COMPRESS                      = "/usr/bin/gzip -c";
	$ZCAT                          = "/usr/bin/zcat";
	$LHA                           = "/usr/local/bin/lha";
	$ISH                           = "/usr/local/bin/ish";

5.5	mget3 の送り返しプロセス

いくつかのファイルをまとめて送り返すプロセスの最終ステージは、次のよう
に行なわれます。

   ○  	mget3 interface はロックがかかっている状態のうちに 
	$TMP_DIR に送り返すべきファイルを作っておきます。
	送り返しプロセスはロックを外した後で行なわれる。

なお $TMP_DIR に作られる中間ファイルは次のようなファイル名になっている。

	m:"モード名":"プロセスID"return.数字(分割されるため)

送り返すものが複数になった時のために”分割の数字”は必要であるのは自明
だが、一意にファイルを定めるためにはプロセスIDとモード名までがセットに
なる必要がある。というのは一つのメールで「複数のモードの mget コマンド
を使う」ことができるからである。

   ○	ロックをはずす (&Unlock();)

というのは、送り返すプロセスが長い場合ＭＬ自体およびその後に来たもっと
手間のかからないプロセスさえもロックして止まてしまうのはいけないからで
ある。

   ○	&RunStartHooks; から mget3_SendingEntry を呼び出す。

mget3_SendingEntry は %mget_list に従い下位インターフェイスを呼び出す。
ロックははずれているので、複数の送り返しプロセスがどう時に走っても構わ
ない。

ファイルが分割されている場合、送り返しは $MGET_SEND_BACK_SLEEPTIME (が
未定義なら $SLEEPTIME) 時間ごとに行なわれる。mget コマンドで明示的に指
定される場合以外はデフォールトの $MGET_SEND_BACK_SLEEPTIME
($SLEEPTIME) が優先される。$SLEEPTIME は $MGET_SEND_BACK_SLEEPTIME の
古い名前である

注意:なお通常の条件下では今送り返そうとしている中間ファイルが 上書きさ
れることはありえない。異常な場合は有り得るだろうが…(そんな状態のOS下
でプロセスはマトモに動かないだろう)

5.6	コマンドで単なるシンタックスエラーの警告をする

明示的に $USE_WARNING をセット
e.g. in config.ph

	$USE_WARNING = 1;

するとコマンドメールでのシンタックスエラーの警告をする。デフォールトは
しない。

e.g. 
# helps 			←コマンドのエラーは警告
#うじゃ				←シンタックスエラー警告なし
#しぐにちゃ〜	uja@uja.ac.jp	←シンタックスエラー警告なし

5.7	mget の送り返し時のファイルサイズ

	$MAIL_LENGTH_LIMIT (default is 1000 lines)

は複数のファイルに分割する時の一通あたりの大きさです。行数で指定します。
Internetならともかく、パソコン通信の人へも配送する時は気を使いますよね
(最近ではそうでもないのか？よくしらない)。

目安としては1000行でだいたい50kくらいになるので1000が選ばれています。

5.8	mget で指定できるファイルの最大数

mget で指定できるファイル数の最大値。デフォールトは1000で mget * など
として1000通以上のファイルを指定するとエラーになる。

	$MGET_SEND_BACK_FILES_LIMIT

5.9	Mget Format: Unix From 形式

4.4BSD UNIX の sendmail は /usr/libexec/mail.local を使い各ユーザ(e.g. 
fukachan) 宛のメールを /var/mail/fukachan に保存しています。
この形式が UNIX FROM 形式です。$HOME/mbox も同様ですね。

	From fukachan Mon Jan 26 09:11:46 1998
	Received: by hikari.fml.org (8.8.8/3.4W6+Hikari-2.1) 
		with ESMTP id JAA02846 for <uja@fml.org>; 
		Mon, 26 Jan 1998 09:11:46 +0900 (JST)
	From: fukachan@sapporo.iij.ad.jp
	Subject: uja

	なんとなくです。なんとなく

MH の inc はこの形式のファイルを処理することを前提にしています。

5.10	Mget Format: MIME/MultipartのBNF表現（RFC1521より）

   boundary := 0*69<bchars> bcharsnospace

   bchars := bcharsnospace / " "

   bcharsnospace :=    DIGIT / ALPHA / "'" / "(" / ")" / "+" /"_"
                 / "," / "-" / "." / "/" / ":" / "=" / "?"

   Overall, the body of a multipart entity may be specified  as
   follows:

   multipart-body := preamble 1*encapsulation
                  close-delimiter epilogue

   encapsulation := delimiter body-part CRLF

   delimiter := "--" boundary CRLF ; taken from Content-Type field.
                                   ; There must be no space
                                   ; between "--" and boundary.

   close-delimiter := "--" boundary "--" CRLF ; Again, no space
   by "--",

   preamble := discard-text   ;  to  be  ignored upon receipt.

   epilogue := discard-text   ;  to  be  ignored upon receipt.

   discard-text := *(*text CRLF)

   body-part := <"message" as defined in RFC 822,
             with all header fields optional, and with the
             specified delimiter not occurring anywhere in
             the message body, either on a line by itself
             or as a substring anywhere.  Note that the
             semantics of a part differ from the semantics
             of a message, as described in the text.>

5.11	Mget Format: MIME/Multipartの見本

Date: Thu, 18 May 95 22:33:00 JST
From: Elena@phys.titech.ac.jp (Elena Lologrigita)
Subject: P R E S E N T
To: fukachan@phys.titech.ac.jp
MIME-Version: 1.0
Content-type: multipart/mixed;
	boundary="--Thu_18_May_95_22:32:56--"

----Thu_18_May_95_22:32:56--
Content-Type: message/rfc822

Date: Thu, 18 May 95 21:45:17 JST
From: fukachan@phys.titech.ac.jp
Subject: あほうどり
To: Elena@phys.titech.ac.jp (Elena Lolobrigita ML)
Message-ID: <19950518.01905.Elena.Lolobrigita@Baycity.asia>

「なんとなく いいかんじだな〜 そのほうがおもしろいし 」
につきますね、この番組
「明日に」でも「明日へ」でも「明日」でもない「あしたキックオフ」なんで
すよ(う〜ん、なんとなくわかるが(笑))

(ふ):やっぱり、#3、#7、#12、#23、#27、#32 ですね(^^)

----Thu_18_May_95_22:32:56--
Content-Type: message/rfc822

Date: Thu, 18 May 95 22:00:29 JST
From: Elena@phys.titech.ac.jp
Subject: あしたキックオフ
To: Elena@phys.titech.ac.jp (Elena Lolobrigita ML)
Message-ID: <19950518.01906.Elena.Lolobrigita@Baycity.asia>

はまるとあの変な雰囲気から抜けられなくなります（笑）やっぱり 
アミノテツロー の謎のマニアックな味？とでもいうのがこの番組が
一番全壊^H開してますね。
もちろん 脚本・シリーズ構成：山本優 あっての「フリーキック」ですなぁ

----Thu_18_May_95_22:32:56----

5.12	Mget Format: RFC934

rfc934 "Proposed Standard for Message Encapsulation"

MH の burstで複数の展開に展開できます。

Example:
------- Forwarded Message

From: Anna
Subject: Mama told me

やっぱり「あほうどり」ですね。シリーズの核心です。
脚本：山本優	絵コンテ：アミノテツロー	演出：鈴木敏明

------- Forwarded Message

From: Elena
Subject: Albatros

イングリッドは隼の妹という根も葉もあるような話が…（笑）

------- Forwarded Message

5.13	Mget Format: RFC1153 digest 

comp.sys.ibm.pc.digest とかでみるでしょ？あれです。RFC は aboutすぎて
読んでもよくわかりません;_;

Example:

Date: Sat, 20 May 95 01:33:50 JST
From: Elena@phys.titech.ac.jp
Subject: Freekick
To: fukachan@phys.titech.ac.jp

GODAI BBS DIGEST	Sat, 20 May 95	Volume 95: Issue 120

Today's Topics:
	エレナさんの特技は？ 

------------------------------

Date: Sat, 20 May 95 00:00:31 JST
From: "Ken'ichi Fukamachi" <fukachan>
Subject: 	エレナさんの特技は？ 
X-Mail-Count: 01932

エレナさんの特技は水撒きだってば(^^) 水撒き

--fukachan 
「とんでもだめだよ、おにいちゃん。アルバトロスは風にのるんだ」

------------------------------

End of GODAI BBS Digest V95 Issue #120
********************************

5.14	Mget Format: 1153 のカスタマイズ

$RFC1153_ISSUE		ＭＬの記事番号ではなく1153形式で送り出す時の番号

$RFC1153_SEQUENCE_FILE	その番号を保存するファイル

		このルーチンが呼ばれるたびにカウンタは進みますが、
		前述のように各ユーザごとに1153で送る場合を考えると
		送り方はそれぞれ違うのだから
		番号はちゃんとつながってはくれません。
		これを解決する方法はありません

$RFC1153_LISTNAME 	まとめ送りする1153 digest につけるタイトル

$RFC1153_VOL		Volume 例えば96年度のまとめ送りなら Volume 96の
			ようなレベルの番号

$RFC1153_CUSTOM_HOOK	&Rfc1153Custom($mode, *conf) の中で
			行なわれるフック

&Rfc1153Custom($mode, *conf) internal:

    ########## CUSTOMIZE BELOW ##########
    $issue     = $RFC1153_ISSUE    || 1;
    $listname  = $RFC1153_LISTNAME || "UJA";
    $vol       = $RFC1153_VOL      || $year;
    $IssueSeq  = $RFC1153_SEQUENCE_FILE  || 
	"$FP_VARLOG_DIR/IssueSeq"; # file to remember count;

    &GetTime;
    &eval($RFC1153_CUSTOM_HOOK, 'RFC1153 custom:');
    $issue = &Rfc1153GetSeq($IssueSeq);

5.15	Mget Format: lzh + ish option

FYI: 一部のOS(Sun OS 4.x ?)で 2.2 でうまく動かない時に 
$INSECURE_SYSTEM = 1; を設定すると動くことがあります。
See also: 9.15 

	mget 200-210 ish

の用に指定するとlzh して ish(s7 mode)したものを送り返します。

	$LHA = "/usr/share/bin/lha";
	$ISH = "/home/axion/fukachan/bin/ish";

等をどこかで(config.ph or sitedef.ph)で設定して下さい。makefml が自動
探索て設定されているはずですが確認はして下さい。

5.16	SJIS にファイルを変換して送る （lzh + ish と lhz + uuencode option）

config.ph で $USE_SJIS_IN_ISH = 1; をセットすると lha を使うタイプでは 
SJIS に変換します。変数名は ish だけのように見えますが歴史的なものです。
lha を使うならいづれの場合にも適用されます。

^M ^Z もつけます。すべて、外部コマンドを使わずに自力でやります。

6	FML のプロセス

ＭＬサーバの基本動作を知っておくとカスタマイズの時役にたちます。

6.1	ＭＬサーバの動作 (fml と sendmail の役割分担)

   メールが SMTP で送られてくる

             ↓

   SMTP で待ち構えているプログラムがうけとる (例: sendmail)

             ↓

   /etc/aliases から何をすれば良いのかを理解して、
   setuid 操作等を行なった後 fml.pl の STDIN にメールが送り込まれる。

             ↓

   (sendmail -> fml.pl へ引き渡される。ここからが FML の担当)
   config.ph による設定に従い、ヘッダの解析、ＭＬメンバーのリストに従い
   配送 or コマンド要求を処理した結果のメールを配送リストと共に
   sendmail 等のSMTPサーバへ引き渡す

             ↓

   (ここから再び sendmail の担当)
   sendmail 等のSMTPサーバがメールの配送を行なう。

フィルタだけなら sed でも十分だし"配るだけ"なら Sendmail 8.x でも十分
でしょう。しかし、+αでログをとり、スプールし、必要なら取り寄せられる
ようにちょこっとだけ複雑なことをしようとするならこのサーバ まで必要と
なるというわけです。

なおこの図でわかるとおり、まとめおくりはこれとは"全く別の"プロセスです。
まとめおくりは自動的に作動するわけではありません。
まとめおくりとは、一定時間ごとにスプールされたＭＬの記事を送ってあげる
"別のプロセス"です。このプロセスは別の仕掛けで定期的に実行されなければ
なりません。
See also: digest 2 
See also: digest 2 

6.2	Sendmail -> fml.pl 時の動作

sendmail から fml.pl へメールが渡される時は次のように動作します。

○ まず /etc/aliases にある

	Elena: :include:/usr/local/list/Elena
	owner-Elena:fukachan

のような部分から /usr/local/list/Elena を実行すればよいことがわかるの
で sendmail はこのファイルを実行します。/usr/local/list/Elena の中身は

	"|/usr/local/fml/fml.pl /var/spool/ml/elena"

のようになっています。

次に fml が上の引数は /var/spool/ml/elena を Elena ML の HOME だと見な
し /var/spool/ml/elena/config.ph に従い fml の設定を行います。

そのあと設定に従いメールを処理します。 コマンドラインオプションを指定
するときは /usr/local/list/Elena の中で

	"|/usr/local/fml/fml.pl /var/spool/ml/elena --ctladdr "

のように書きます(コマンドラインオプションについては Chapter debug 4)。
引数の書き方の順番は任意ですが、引数の中の最初の directory を ML の 
HOME (config.phのある場所 もしくは spool やメンバーファイルのある場所) 
と見なします。

6.3	ライブラリのファイルを探す順番 (fml.pl と ARGV)

	/usr/local/fml/fml.pl /var/spool/ml/elena

のように起動されるわけですが、この場合/usr/local/fml/fml.pl の 
/usr/local/fml 部分をとりだし /usr/local/fml を実行ファイルやライブラ
リのパスとみなします。

	1   /var/spool/ml/elena 
	2   /usr/local/fml 

この順番で dynamic loading するファイルを探します。例えば config.ph や 
libsmtp.pl をこの順番で探します。もし、この後に directory 名がさらに付
け加えられていた(複数可能)場合、例えば

   "|/usr/local/fml/fml.pl /var/spool/ml/elena /usr/lib/uja /lib/aja"

の時は

	1   /var/spool/ml/elena 
	2   /var/spool/ml/etc/fml/
	3   /usr/local/fml 
	4   /usr/lib/uja
	5   /lib/uja

のような順番でファイルを探します。

6.4	設定ファイルのサーチ順番

オプション設定の強い順番に並べると

	1 コマンドラインオプション (fml.pl -d や fml.pl --ctladdr 等)
	  なおコマンドラインオプションについては Chapter debug 4。
	2 sitedef.ph による設定のoverwrite(サイト共通の設定等が望ましい)
	3 各MLごとの config.ph による設定
	4 site_init.ph によるデフォールト設定	
	5 fml デフォールト設定

普通の program と同様ですね。ＭＬごとではなくそのマシン共通の設定にな
るもの

	tar や gzip はどこにある？

等を sitedef.ph に書くと便利でしょう。

site_init.ph は各MLの config.ph の前に評価されデフォールトを決めます。
sitedef.ph は各MLの config.ph の評価後に適用され、各ＭＬの設定を強制的
に書き換えることもできます。それぞれ使いわけると良いでしょう。いずれに
しろ config.ph にない変数であればどちらを使っても同じことです。

sitedef.ph site_init.ph のサーチは

				Example
	-----------------------------------------------
	$DIR			/var/spool/ml/elena/
	$ML_DIR/etc/fml/	/var/spool/ml/etc/fml/
	$EXEC_DIR		/usr/local/fml/
	perl standard path	@INC

の順にサーチされます。共通の場所なので

	$ML_DIR/etc/fml/	/var/spool/ml/etc/fml/
	$EXEC_DIR		/usr/local/fml/

のいづれかでしょう。fml 2.2.1 で $ML_DIR/etc/fml/ が先頭になりました。
これはversion up時に/usr/local/fmlの下をいじらなくてもよいようにという
配慮からです。

6.5	fmlのプロセス(STDINからの読み込みの第一段階)

STDIN からの読み込みは第壱段階でハッシュテーブル %Envelope

	ヘッダ	$Envelope{'Header'}
	ボディ	$Envelope{'Body'}
See also: 7.3 
See also: 7.3 

に保存されます。この時ボディ(メールの本文)に対しては次のようなチェック
がなされます。

○ 最初の $GUIDE_CHECK_LIMIT 行に対して $GUIDE_KEYWORD のキーワードが
現れるか否か？
メンバー以外からのメールでこのキーワードをキャッチした場合は、ガイドを
送り返してそれ以外のことはしない。

○ 最初の $COMMAND_CHECK_LIMIT 行に対して
	^#(\s*\w+\s|^\#\s*\w+)
	^#$CHADDR_KEYWORD

	# で始まり、英文字が続く行 (\s*\w+\s|^\#\s*\w+)

	# で始まり、$CHADDR_KEYWORD のキーワード
	が現れる行があるか否か？あった場合はコマンドモードへ移行。

の2つのチェックをしています。それぞれの LIMIT を調節すると、つまり 
LIMIT を 0にすればチェックをしないということになるし、全文すべてをコマ
ンドの対象にすることもできます。デフォールトではそれぞれ最初の3行のみ
を対象にしています。

なお、それぞれのキーワードデフォールトは次のように設定されています。

	$GUIDE_KEYWORD  = "guide";
	$CHADDR_KEYWORD = "chaddr|change-address|change";

6.6	fmlのプロセス(第２段階, %Envelopeの処理)

%Envelope にヘッダとボディを読み込んだ後はヘッダの解析プロセスが続きま
す。詳細については次の章を見て下さい。
See also: 7.3 
See also: header_rewrite 5 
See also: 7.3 
See also: header_rewrite 5 

この後ロックして、メインのプロセスが続くことになります。

6.7	fml process の lock と signal handling 

現在の flock を使うロックアルゴリズムは次のように設定されています。
flock(2) と alarm(3) によるTIMEOUT処理による一般的な方法です。 
sendmail のような alarm(3) ベースの event 駆動をするようにプロセス管理
をしています。

NT4 上では Activestate ntperl を使っています。この ntperl では 
flock(2) は動きます(かなり怪しいという話も聞くが詳細は不明)が alarm(3) 
がないので Win32::Process による wrapper で alarm(3) を emulate してい
ます。emulation といってもTIMEOUTしたら強制終了するだけですが。

sub Flock {

    &SetEvent($TimeOut{'flock'} || 3600, 'TimeOut') if $HAS_ALARM;
	...

TIMEOUTを待つ時間は $TimeOut{'flock'} で決まります。(flock でない場合
は 3秒+α 程度の sleep を $MAX_TIMEOUT 回して待ってみる)

    # signal handling
    $SIG{'ALRM'} = 'TimeOut';
    $SIG{'INT'}  = $SIG{'QUIT'} = 'SignalLog';

$TimeOut{'flock'} (デフォールトは3600秒)後 $SIG{'ALRM'} で定義された関
数(TimeOut)を実行します。

関数 TimeOut は管理者へ TIMEOUT を知らせ、ログを残しfmlを終了します。
これがないとずっとロック(flock)がかかったままになるからです。

なお flock を使わない時はTIMEOUTしたメールを保存し管理者へ TIMEOUT を
知らせます。詳細は liblock.pl を見るとわかるでしょう。
See also: references 1.1 
See also: references 1.1 

6.8	イベント・スケジューラ

TIMEOUT 等は現在実行している処理内容によらず特定の時間が来たら(割り込
んで) 実行する必要がありますがそれは伝統の味 alarm(3) を使って実装しま
す。なお Windows NT 4.0 Version では alarm(3) が使えないのこの処理は実
行されません。

6.9	ロックの仕方(flock でない場合)
See also: troubleshoot 9.2 

ロックアルゴリズムは二通り用意されてます。flockがお奨めです。flock(2) 
参照

	$USE_FLOCK    = 1; (default 1)

で flock system call

	$USE_FLOCK    = 0;

で大昔からある link(2) を使う方式を使います。この方式はロックするファ
イルへの link() ができるか否か?を排他制御に使います。このロックするファ
イルは

	$LOCK_FILE

という変数で変更できます。デフォールトは $DIR/var/run/lockfile.v7 です。

	"$FP_VARRUN_DIR/lockfile.v7"

つまり ML の home の下の var/run/lockfile.v7 です。この方式の問題は OS 
がいきなり落ちた時にこのファイルが残ってしまうので手動でこのファイル群
を消さなければならないという点が最大の問題点です。そのため flock() の
ようなOSが直接ロックを支援する形が望ましいです。

そういう場合は reboot 直後に

	"$FP_VARRUN_DIR/lockfile.v7"
	"$FP_VARRUN_DIR/lockfile.数字"

すべてを消して下さい。

fmlの何かプロセスが走っている状態ではどのロックファイルを消していいか
はプロセステーブルを見る必要があります。数字はプロセス番号ですからプロ
セステーブルを見て(ps(1))、該当する数字(fml の process)がなければ、そ
のファイルは消して良いです。

なお link(2) スタイルの場合 $MAX_TIMEOUT 秒後、var/log/ の下にTIMEOUT
したメールは保存され管理者へTIMEOUTが通知されます。

[捕捉]	flock(2) を見れば分かりますが 

	$LOCK_SH                       = 1;
	$LOCK_EX                       = 2;
	$LOCK_NB                       = 4;
	$LOCK_UN                       = 8;

         #include <sys/file.h>
         #define   LOCK_SH   1    /* shared lock */
         #define   LOCK_EX   2    /* exclusive lock */
         #define   LOCK_NB   4    /* don't block when locking */
         #define   LOCK_UN   8    /* unlock */
    
         int
         flock(int fd, int operation)

排他制御については例えば A. S. Tanenbaum, "Modern Operating Systems" など

7	FML 内部におけるデータ構造

ここでは fml 内部処理におけるデータ構造について解説します。これらの知
識は改造する上で必須の事柄でしょうが、単に変数を 1 or 0 にセットするだ
けしか設定 (config.ph) をいじらないなら読む必要はないでしょう。

7.1	変数名の naming convention

○ 大文字（[A-Z0-9_]+）だけの塊はユーザーのカスタマイズで使う目的の
   Global 変数です。

	Example:	$MAIL_LIST

○ "1単語の先頭一文字が大文字、残りは小文字"の塊からなる単語はメー
   ル本体やヘッダをSubroutine間で渡しあうための Global 変数です。

	$MailBody	$Reply_to
	%Envelope	*_cf

	例外： *_cf は システム情報をもっている名前空間です。
	(_cfはほとんど使われていません。将来は消去すべきです)

   %Envelope は最も重要な変数です。
   しかしながら、こういうグローバル変数は本来出来るだけ少なくするべきです。
   また、@Fld にように現在グローバルとして使われていないのに名残として
   残ってしまっているものもあります。
   が、これはもぉこのまま使うしかないようです。

   注意：
	$debug だけは全部小文字でグローバル変数という例外です。
	便利だからというのと、歴史的にそうなっているというだけなので
	今後そういう変数名は作られることはありません。
	また、昔ユーザ定義で今は内部変数扱いになった $ML_MEMBER_CHECK も
	例外です。

○ 小文字は基本的にlocal variableで、大抵はsubroutineの先頭でlocal宣言
   されています。

○ 補足
なお、Directory を定義する $*_DIR タイプの変数には

	$*_DIR 		$DIR からの相対パス
	$FP_*_DIR 	絶対パス

の２種類があります。 $FP_*_DIR タイプの変数は自動的に変換され定義され
ます。基本的には絶対パスが使われます。$FP_ の変数は fml.pl の初期化で
自動的に補正されつつ設定されます。ほとんど全ての場面で絶対パスを用いま
す。

	$FP_TMP_DIR
	$FP_VARDB_DIR
	$FP_VARLOG_DIR
	$FP_VARRUN_DIR
	$FP_VAR_DIR
    	$FP_SPOOL_DIR

7.2	関数名の Naming Convention

一部の例外を除いて”１単語の先頭一文字が大文字、残りは小文字”の塊から
なる単語です。基本的に subroutine の名前はX11風だったりします。最近の
はlisp風味も混ざってます:-) #おおむねX11風ですね

○ fml 1.5 以降では若干例外があります。

ファイル操作をする関数で

	変換インターフェイスとしての 	f_関数 名
	＃いつか、なくなるだろう

		と 

	そのモードのコンストラクタ	Cnstr_関数 名
	そのモードのディストラクタ	Destr_関数 名

が例外です。「将来 replace するべきです」と当時言ったまま replace され
ないままですが:-)

7.3	%Envelope (ハッシュテーブル)

%Envelope には今 fml を起動したメールの内容(ヘッダ、ヘッダの各フィール
ド、本文等)が格納されます。また、そのメールに対しどういうMETHODでREPLY
を返すべきか？や、sendmailとの通信等の設定に関しての付加情報も 
%Envelope を通じて渡されます。それはこのメールに対する METHOD の定義と
みなしているからです。

sendmail の struct envelope e; に対応するものです。
しかし、perl 4 を本来ターゲットにしているため

	$Envelope->$Header->$From = "uja@domain";

のような使い方はしません(できない)。これと同様のことを意図したシンタッ
クスが

	$Envelope{"h:From:"}  = "uja@domain";

で表現されています。 h = header で From: はわざと Field だとわかりやす
いように : まで含めています。

以下 %EnvelopeのKEYについて説明します。
＃ハッシュなので、KEY => VALUE が $Envelope{KEY} の値が VALUE です

	h: ではじまるものKEYは「ヘッダの各フィールドのデータ」です。

	h:Capital:	補正されたデータ e.g. h:Subject:
	h:lower-case:	元メールのデータ e.g. h:subject:

	それ以外に その Envelope のメールをどういうモードで処理するか？
	や、そのメールへのREPLY、エラーレポート処理をどうするか？
	というMETHODの指定等の付加情報も付け加えることもあります。

	[ヘッダ関係]

	h:field:	上述のヘッダ：フィールド：設定値

	fh:field:	field(小文字) は fml.pl がある値を強制する

			例： fh:to: は To: を $Envelope{'fh:to:'} の値にする

	oh:field:	field は original のヘッダフィールドを使う

	GH:field:	コマンドの結果を返すメールは GenerateHeader() という
			ルーチンでメールヘッダを生成する。
			そこでの値を変更したいならこのKEYを使う。

	Addr2Reply:	コマンドの結果の返事を返すアドレス
			reply-to: > From:

	[メールが呼び出すべきモードやメソッドのConfig]

	macro:x		x は sendmail の $x に対応する内容を保存

	mode:x		モード設定値 

	mci:mailer	mci は Mail Connection Information (MCI)
			mci:mailer は ipc(SMTP) か prog(exec sendmail)
			のどちらかである

	[内部表現]

	Header		元メールのヘッダ
	Body		元メールのメール本文
	Hdr		送り出すメールのヘッダ（&Smtpの直前に生成される）

	message		メールをサーバへ送ったユーザへのメッセージ
	error		管理者への(エラー)メッセージ

	MIME		ISO-2022-JP is detected (toggle Flag)
	UnixFrom	Unix From
	Hdr2add		$SUPERFLUOUS_HEADER の時につかうバッファ
	nclines		# command の行数
	nlines		メール本文の行数
	preamble	メール本文の前につける文章
	trailer		メール本文の後につける文章

	tmp:x		temporary used

例: Subject:

   $Envelope{'h:subject:'} は来たメールそのもの

   $Envelope{'h:Subject:'} は来たメールの Re: をとり
   必要なら [Elena 100] のようなものを処理したもの

のような違いがある。配送されるヘッダと大文字ではじまる単語は次のように
対応する。

配送メールのヘッダ: %Envelope

        Field           key in %Envelope
	--------------------------------------- 
	Date: 		h:Date:
	From:		h:From:
	To: 		h:To:
	Subject: 	h:Subject:

7.4	データ構造の初期化

各データの初期化は次の順序で行なわれる。

	$DIR $LIBDIR @INC の初期化

	&InitConfig
	   &SetDefaults
		%Envelope
		DNS, @HdrFieldsOrder, and others

	   &LoadConfig
		$DIR/config.ph
		sitedef.ph

   	   &SetOpts
		command line options

	   COMPATIBILITY CODE

	&Parse
		%Envelope へ Header Body 等の元々の内容を保存

	&GetFieldsFromHeader
		%Envelope へ h:field: および h:Field: をセット

	&FixHeaderFields
		h:Field: への各種補正を行なう

	&CheckCurrentProc
		%Envelope による設定、動作モードチェック

	この後各種フックがそれぞれの場所で評価される。

	Example:
		$START_HOOK
		$SMTP_OPEN_HOOK
		$FML_EXIT_HOOK

この後ロックされ、ロック下でクリティカルな作業が行なわれる。作業が終る
まで alarm(3) による割り込み以外ではこのロックははずれない。

7.5	ディレクトリ変数
See also: 6 

起動時の一番最初の段階では $DIR $LIBDIR @INC という変数の設定を筆頭に
各種変数の初期化が行なわれます(上述)。$DIR $LIBDIR @INC が起動時にどう
評価され使われているかは「fml の基本動作と起動オプション…」の章を見る
と分かるでしょう。
See also: 6 

以下では DIRECTORY 一覧を示します。

	@INC	(参考)
		これは Perl の include file の search path
		$DIR @INC(original) $LIBDIR ...
		の順番に探される。

	$DIR
		config.phのある場所、いわゆるMLのHOME	
		@INC の先頭に設定される

	$LIBDIR	
		fml.pl や libsmtp.pl 等の置き場所。
		$DIR と同じでも良いし、別の場所で保守されていてもよい。
		もともと複数のＭＬを扱うためにスプールと *.pl ファイル
		群の置き場所をわけるために導入された。@INC の最後に入る。

		なおコマンドラインに出てくるdirectoryはすべて @INC に
		設定されるが、$DIR の直後の directory が $LIBDIR に設
		定される。

		@LIBDIR にも入っている

    	$SPOOL_DIR		$DIR/spool
		ＭＬの記事を格納する場所

	[$DIRからの相対パスで設定されるもの]

	$TMP_DIR		tmp (temporary)	4.4BSD の /tmp
	$VARDB_DIR		4.4BSD の /var/db (データベース)
	$VARLOG_DIR		4.4BSD の /var/log に対応 ログが置かれる
				backward compat のため
				log 等のデフォールトは $DIR/log のままである
				(本来は $VARLOG_DIR/log が望ましいだろうが)
	$VARRUN_DIR		4.4BSD の /var/run pid-file 等はここ
				なお cache もここにおいている。
	$VAR_DIR		4.4BSD の /var

	[FULL PATH 化された変数]

	$FP_TMP_DIR		$DIR/$TMP_DIR
	$FP_VARDB_DIR		$DIR/$VARDB_DIR
	$FP_VARLOG_DIR		$DIR/$VARLOG_DIR
	$FP_VARRUN_DIR		$DIR/$VARRUN_DIR
	$FP_VAR_DIR		$DIR/$VAR_DIR
    	$FP_SPOOL_DIR		$DIR/$SPOOL_DIR

7.6	$TMP_DIR について

ＭＬサーバの作業エリアにはデフォールトでは $DIR/tmp (つまり $TMP_DIR =
'./tmp';) を使います。変更したい場合は $TMP_DIR を変更して下さい。

/tmp とか /usr/tmp とかは万が一ファイルが残ると嫌なので使いません。
private communication のファイルを public な場所にファイルを残すことは
しないためです。

その他にも 4.4BSD 風の directory 構造の中に各種のログやキャッシュが保
存されます。

7.7	設定ファイル群
See also: 8 

[メンバーのリスト関係]

	$MEMBER_LIST 	 	$DIR/members
See also: 8 

	メンバーリスト(認証のみに使う)

	$ACTIVE_LIST 		$DIR/actives
See also: 8 

	ＭＬの配送リスト

	$REJECT_ADDR_LIST	$DIR/spamlist
See also: filter 2.13 

	投稿/コマンド/自動登録をはじめとして全ての場合について、弾きた
	いアドレスのリスト。自動的に登録する機能もある。

[各種の説明、ご案内関係のファイル]

	$OBJECTIVE_FILE	 	$DIR/objective

	ＭＬの目的を書いたファイル

	$GUIDE_FILE		$DIR/guide

	ＭＬの一般向けご案内（ガイド）

	$HELP_FILE	 	$DIR/help

	ＭＬのHELP、コマンドの解説等

	$DENY_FILE	 	$DIR/deny

	ＭＬがメンバーチェックをしている時
	メンバー以外からメールが来た時に返す断りの文章

	$WELCOME_FILE	 	$DIR/guide
See also: how_to_subscribe 4 

	ＭＬが自動登録の時、登録時に送ってあげる文章

	$CONFIRMATION_FILE       $DIR/confirm
See also: how_to_subscribe 4.9 

	自動登録で confirmation モードの際 reply を返す 
	confirmation の説明のファイル

[ログファイル関係]

	$LOGFILE	 	$DIR/log

	ログ

	$MGET_LOGFILE    	$DIR/log
See also: 5 

	mgetのログ。デフォールトでは↑ログファイルと同じ

	$SMTPLOG		$VARLOG_DIR/_smtplog

	プロセス間通信(SMTP)のログ(デバッグの役に立つ)

	$SUMMARY_FILE 	 	$DIR/summary	

	MLの記事のサマリ

	$SEQUENCE_FILE 	 	$DIR/seq

	MLの記事番号

	$MSEND_RC		$VARLOG_DIR/msendrc
See also: digest 2 

	まとめおくりの制御ファイル

	$LOCK_FILE	 	$VARRUN_DIR/lockfile.v7

	flock() を使わない時のロックで使うファイル

	$LOG_MESSAGE_ID		$VARRUN_DIR/msgidcache

	message-id cache ファイル
	(ML自身での無限ループを防ぐためのキャッシュ)

	$MESSAGE_ID_CACHE_BUFSIZE

	Message-ID cache ファイルサイズ

	$INDEX_FILE		$DIR/index

	このファイルはなくても構わない。indexコマンドで表示したい内容
	を書く。このファイルがない場合はその場でMLのHOME内容を調べて返
	す。

7.8	単に便利なためにある変数

	$DO_NOTHING

	何もしないという分岐をするための変数。特殊なサーバを作る時や
	特別なHOOKをかけたりする場合に有用である。

	$NULL

	ダミー:-) ＃ 別にこんな変数いらない 
	#define null (char *)0 みたいなものだと思ってもらえば良い

	$FML	

	カーネル内のプロセステーブルを書き変える際に使う変数

	$FACE_MARK

	(単なる愛敬:-)。各種リクエストの結果を返す時にお別れの文章の腋につける
	e.g. 	P(^^)
		Be seeing you P(^^)
	のようになる。

	$INCLUDE_SIM_PATH

	Simulation で使う。気にしないで下さい:)

	$UNISTD

	Declare "Unix Standard" flag. undefined on Windows NT4

	$LOCKFILE

	lock file variable in some libraries. It may be uncontrolled
	by a user.

	%MAKE_FML

config.ph に現れるハッシュ %MAKE_FML は makefml で使うためのものです。
makefml 以外では使われません。現在では使われていません、無視して下さい。

○ 古い変数として他の名前に置き換えられたもの

   $GUIDE_REQUEST	-> $GuideRequest
   $RPG_ML_FORM_FLAG	-> $COMMAND_SYNTAX_EXTENSION

○ obsolete なもの

   $NON_PORTABILITY

7.9	内部で使われている変数を調べるには？

config.ph で 

	$DUMPVAR = 1;

やコマンドラインで

	fml.pl --DUMPVAR 引数

として fml を呼び出すと全ての変数を dump します。この場合はPerlについ
てくる dumpvar.pl ライブラリを利用し、名前空間から変数リストを引っ張り
出しています。

ちなみに fmlserv.pl は同様のやり方で名前空間の switch を利用して複数の
ＭＬを疑似的に実行しています。

8	FML 設定ファイルのフォーマットと構造

fml の設定ファイル、メンバーリストは基本的に shell like な構造で記述さ
れていると期待されています。つまり基本的に # ではじまる行はコメント、
空行は飛ばす等の挙動を各ルーチンはしています。

以下では各設定ファイルのフォーマットについて言及します。

8.1	members ファイルのフォーマットと構造

生のファイルのフォーマットは後述のようなものです。コマンドの挙動は 2.2 
以前と以後でちょっと違います。2.2 以降のmembersコマンドでは一般ユーザ
には下のようなフォーマットは見えません。すでにいなくなったメンバーの情
報をだすべきではないからです。admin members では後述する生のフォーマッ
トが見えてしまいます。一応知っておいて下さい。

$MEMBER_LIST (default members) で定義されるファイルは

	#.FML
		…fml が自動的につけるコメント…
	#.endFML
	アドレス1
	アドレス2
	# アドレス3
	##BYE アドレス4
	アドレス5

のような形をしています。歴史的理由により現在では

   # の後空白 でコメントアウトされていてもメンバーチェックの対象になる
   ## ではじまるところはコメント

となっています。よって上の例では ##BYE の行は無視されますが、それ以外
の アドレス1 〜 アドレス5 (4を除いて) すべてがメンバーチェックの際には
対象となります。

［歴史］
この動作は 1.2 release version の直後、自動登録を拡張する際に導入され
ました。またこの導入のため # off と # skip はどう違う？という疑問がそ
の後生まれることになりました。

なおメンバーファイルとしては各行のアドレスより後ろの部分は
何にも使われていませんので、勝手に使って構いません。

しかしながら、自動登録の場合は $MEMBER_LIST と $ACTIVE_LIST は同じもの
（$MEMBER_LIST）が使われます。よってそのフォーマットは $ACTIVE_LIST 形
式であると仮定する必要があります。

8.2	actives ファイルのフォーマットと構造

$ACTIVE_LIST (default actives) で定義されるファイルは ＄MEMBER_LIST と
同様の構造を持ちます。

しかし actives ファイルは拡張された表現として各アドレスのオプションを
行の残りの部分に持つことができます。

	アドレス	オプション	# コメント

	注意：なお、それぞれの↑ブロックの間には必ず一つ以上の SPACE
	か TAB があると仮定しています。

よって勝手に何かを書いた場合オプションとみなされます。付加情報は # コ
メント として行の最後にでも書いて下さい。この辺は shell と同じです。

オプションは V1 と V2 フォーマットがあります。

   V1 フォーマットは

	数字(フォーマット)	まとめおくりの指定
	数字以外		リレーサーバ

   V2 フォーマットでは将来の拡張のため

	m=まとめ送り指定
	r=リレーサーバ
	s=1(skip を意味する)

のように alphabet=option-value の形で定義されています。現在のところこ
れ以外のキーワードは将来のために予約されています。

現在のルーチンは V2 のみを理解します。よって V1 -> V2 に変換する必要が
あります。この変換は

	libfml.pl で ChangeMemberList が呼ばれた時

つまりメンバーリスト等へのなんらかの変更を行なう時に自動的に行なわれま
す。

8.3	actives と members の違い

フォーマット的には上述の通りです。後は自動登録の章で述べられている通り
members はメンバーであるか否か？の認証、 actives は配送リストです。

自動登録では members 一つを認証と配送リスト両方に使っています。そのた
め表現の拡張が必要だったわけです。

8.4	複数のメンバーリスト、複数の配送リスト

	@ACTIVE_LIST	複数の配送リスト
	@MEMBER_LIST	複数のメンバーリスト

を定義できます。地方ごととか組織ごとにリストを管理するのに便利かも知れ
ません。
	@ACTIVE_LIST	plural member lists
	@MEMBER_LIST	plural delivery lists

デフォールトでは @ACTIVE_LIST は $ACTIVE_LIST と同じになります。
@MEMBER_LIST は members と members-admin です。

歴史: 最初に管理者を設定して後はリモートですべてをおこなうという目的の
ために拡張されました。

***
actives members のバックアップについて => daily 6.2

8.5	msendrc ファイルのフォーマットと構造

msendrc は $MSEND_RC で定められる場所におかれます。そのフォーマットは

	アドレス	次回に送る最初の記事番号

です。msednrc は msend.pl が制御するログファイルです。msend.pl は 
$ACTIVE_LIST を見て、

	・あるアドレスがまとめ送りになった
		そのアドレスのエントリを msendrc 内に新しく作る

	・あるアドレスがまとめ送りで”なくなった”
		そのアドレスのエントリを消去

	・まとめおくりを配送した
		次回に送る最初の記事番号を msendrc に記録する		

ということを msendrc に対して行ないます。msend.pl 以外のプログラムが 
msendrc をいじることはありません。

8.6	パスワードファイルのフォーマットと構造
See also: utility_programs 6.17 remote_control 4 

リモート管理の時の認証で用いるパスワードを保存しているファイルは
$PASSWD_FILE でデフォールトでは $DIR/etc/passwd です。フォーマットは
See also: remote_control 4 

	アドレス	cryptされたパスワード

です。つまり UNIX 伝統のパスワードファイル形式の先頭の２つが空白で区切
られたものです。＃crypt(3) についてはマニュアル参照

	$REMOTE_ADMINISTRATION_AUTH_TYPE = "md5";
See also: remote_control 4.6 

と設定されている時は fml.pl の crypt 関数は crypt(3) ではなく MD5 の値
を返すようになります。これは MD5.pm を用いた実装なので perl 5 であるこ
とと MD5-1.7.tar.gz のインストールが必要です。MD5.pm のソースは fml の 
directory に一緒に置いてあります。

admin コマンドには initpass というパスワード初期化コマンドがあります。
あるアドレスをこのファイルへ登録する時などは makefml passwd を使うと良
いでしょう。makefml の使い方については INSTALL ファイルを参照。

8.7	FMLインストール後の maintenance と version up に関して

install は makefml install を使います。version up も同様にして下さい。
というのはインストールするOSなどに依存することがあるので、makefml
install を使うべきだからです。なにをやっているか知っている人は別に cp 
でも構いません:)

version up の仕方は、例えば次のようになるでしょう。

	% cd /var/tmp
	% tar zxvf fml-current.tar.gz
	% cd fml-version番号他の名前
	% make install

以下では例として
	/usr/local/fml に executable
	/var/spool/ml/elena に elena ML
ということにしましょう。

makefml install はいつでも /usr/local/fml に executable やライブラリを
入れるだけです。version up の際に違うことは既にあるＭＬ群に対してロッ
クをしてからインストール作業を行なうことだけです。/var/spool/ml/elena 
の下つまり config.ph 等は変更を受けません。

fml.pl を筆頭に lib*pl 群は overwrite されますから自分でいじってしまっ
ている場合は一旦バックアップを取っておくことが必要です。

メインテナンスを楽にするにはコマンドのパスやＭＬ全体共通の設定はファイ
ルに全部書いておくべきだし、可能な限りHOOKなどにするべきです。例えば

	$HOME/libexec/fml/sitedef.ph 

で行ない各ＭＬごとの設定は

	$HOME/w/spool/fml-support/config.ph 

で制御するなどの運用ポリシーを立てておくことも大事です。

9	Security 

9.1	Security 関係の基本思想

基本的に

   1	デフォールトではすべてを認めない
   2	大丈夫と思われるものを通すようにする
   3	疑わしきものははじいて判断をＭＬの管理者へあおぐ

という風に構成されています。

9.2	Security Check Routine

ファイアウォールでも同様ですが、概念的に２種類の考え方が出来ます。

	1 明らかに危ないものを除いていく
	2 安全なものを許可していってそれ以外は拒否する
	1 deny all, permit secure conditions
	2 permit all, deny known insecure conditions.

fml は 1 のポリシーを採用しています。fml-support: 00950 でも述べていますが

	1.x は外掘から埋める方式 (関数 InSecureP)
	2.y は内掘から埋める方式 (関数 SecureP)

といってます(^^)。1.x と 2.y の関係はそのまま 上の 1 と 2 の違いといっ
て間違いありません。

SecureP は以下のように『コマンドとしてうけいれる命令(メールの一行全体
について実行)の形を限定』します。

    １ 	\w/\w の部分は見逃す。＃ ../ とか .[a.]/ とかはだ〜め
       	/ でOKのところは消去する
	また、まとめ送り等の m=数字 等の特別なシンタックスは消去する。

    ２ 	/^[\#\s\w\-\.\,\@\:]+$/

    の形はゆるす。
    ＃注意： \w は [A-Za-z0-9_] なので、 "-" を加えた

    [Extension]
	ユーザの拡張用に %SECURE_REGEXP というハッシュが用意されています。
	このハッシュ(KEYは適当でよい)のいずれかの正規表現
	にマッチしたら、ＯＫになるように動きます。
	これは YOUR OWN RISK で定義して下さい。

	逆に %INSECURE_REGEXP ハッシュはまずいパターンを記述できます。

    ３ 	これ以外を含んでいたらエラー

    ４ 	特殊なケース（admin コマンドの admin addr m=3) は
	事前に例外処理をした後 &SecureP にまわす。

例：	許される例

   summary
   mget 1-20,30,last:20 mp 1
   mget 10? mp 1			(default では許さない)
   mget 1[012]? mp 1			(default では許さない)
   chaddr fukachan@phys.titech.ac.jp fukachan@beth.phys.titech.ac.jp 

例：	許されない例
   mget `domainname`

例外処理として:

   whois 日本語

をどうしよう？という問題があります。今のところ”通さない”設定のままで
すが、これはこれで何とかするべき問題なのですが、良い解決策はありません。

例：	許されるパターンを拡張する例(%SECURE_REGEXPを使う)

   $SECURE_REGEXP{'whois'} = '\s*whois\s+\033\$[\@B][\041-\176]+\033\([BJ]\s*';

   ＃注意:
   ＃このパターンを調べるべき対象の文字列全体にマッチさせるので
   ＃最後のスペース等がありうるのなら、それらも考慮する必要がある

[捕捉] 許されるコマンドのシンタックス
シェルと関係しています。

Quoted from 4.4BSD:/usr/share/man/cat1/sh.0 
           Shell Patterns
    
           A pattern consists of normal characters, which match them-
           selves, and meta-characters.   The meta-characters are
           ``!'', ``*'', ``?'', and ``[''.  These  characters lose
           there special meanings if they are quoted.  When command
           or variable substitution is performed and the dollar sign
           or back quotes are not double quoted, the value of the
           variable or the output of the command is scanned for these
           characters and they are turned into meta-characters.
    
           An asterisk (``*'') matches any string of characters.   A
           question mark matches any single character. A left bracket
           (``['') introduces a character class.  The end of the
           character class is indicated by a ``]''; if the ``]'' is
           missing then the ``['' matches a ``['' rather than intro-
           ducing a character class.  A character class matches any
           of the characters between the square brackets.   A range
           of characters may be specified using a minus sign.  The
           character class may be complemented by making an exclama-
           tion point the first character of the character class.
    
           To include a ``]'' in a character class, make it the first
           character listed (after the ``!'', if any).  To include a
           minus sign, make it the first or last character listed

NOTE: 1998/11/08 permit "admin add MAR+KUN@DOMAIN " syntax

  +'ed user <addr+ext@domain> (for sendmail users):
	fix to permit this address syntax when automagic registration.
	but not fix to permit command with this addr beautifully.
	# so require more eloborate design

  +'d ユーザのアドレス体系を扱えるように修正

9.3	DNS Spoofing

デフォールトでは何もしていませんが $LOG_CONNECTION がONの時は

	$LOG_CONNECTION = 1;

コネクションを張ってきた相手先のIPアドレスを $PeerAddr に設定します。
firewall 越しだったりすると無意味ですが…$PeerAddr という変数に相手の
ホストのIPアドレスが保存されます。$PeerAddr を使って DNS Spoofing
Check コードをHOOK掛ければよいでしょう。

9.4	Address Spoofing

これは無理っす。もっと下のlayerで何とかしてね。

9.5	SYN Flooding

これもカーネルレベルの話。根本的な対策は難しい。

9.6	Email アドレスの表現とRFC822

	From: なんか / なんか (なんか)

とかいう怪しげなフィールドを作ると経路の途中でエラーになって、その先に
配送されないことがあります。securiity 関係の話なので詳しいことは説明し
ませんが…

それは(設計思想として)「疑わしきものははじく」ということから来ています。
sendmail のソースを読めばなぜ弾くのか理解できます。

RFC822 はBNF表現でできる理論限界を表現している文書です。確かに使っても
構わないのですが、表現のクラスをかなり制限したアドレスを使っていないと
通信できない可能性はあります。

では、どういうものならよいのか？というとすべてを網羅した表現はうまくで
きませんが…

9.7	smrsh.c

smrsh.c は、
	"|program ..."
の program が何を実行するか？ではなく program の名前が /usr/adm/sm.bin 
の中にあるかどうか？を見ています。＃ access(2) で、

よって、/usr/adm/sm.bin/fml.pl ですね:-)

9.8	access(2) 

smrsh.c は access(2) を使っていますが…うぅ

--- NetBSD 1.2REL /usr/share/man/cat2/access.0

CAVEAT
     Access() is a potential security hole and should never be used.

4th Berkeley Distribution     September 15, 1996                             2

--- perl5.003/perl.c

	/* On this access check to make sure the directories are readable,
	 * there is actually a small window that the user could use to make
	 * filename point to an accessible directory.  So there is a faint
	 * chance that someone could execute a setuid script down in a
	 * non-accessible directory.  I don't know what to do about that.
	 * But I don't think it's too important.  The manual lies when
	 * it says access() is useful in setuid programs.
	 */

9.9	Precedence Priority

sendmail 8.8.5 operations manual tells:

             5.7.  P -- Precedence Definitions

                     Values for the "Precedence:" field may be defined
                using  the  P  control line.  The syntax of this field
                is:

                    Pname==num

                When the name is found in a "Precedence:"  field,  the
                message  class  is  set  to  num.  Higher numbers mean
                higher precedence.  Numbers less than  zero  have  the
                special  property  that if an error occurs during pro-
                cessing the body of the message will not be  returned;
                this  is  expected  to be used for "bulk" mail such as
                through mailing  lists.   The  default  precedence  is
                zero.  For example, our list of precedences is:

                    Pfirst-class=0
                    Pspecial-delivery=100
                    Plist=-30
                    Pbulk=-60
                    Pjunk=-100

                People  writing  mailing list exploders are encouraged
                to use "Precedence: list".  Older versions of sendmail
                (which discarded all error returns for negative prece-
                dences)  didn't  recognize  this  name,  giving  it  a
                default  precedence  of  zero.  This allows list main-
                tainers to see error returns on both old and new  ver-
                sions of sendmail.

9.10	4.4BSD vacation

     No message will be sent unless login (or an alias supplied using the -a
     option) is part of either the ``To:'' or ``Cc:'' headers of the mail.  No
     messages from ``???-REQUEST'', ``Postmaster'', ``UUCP'', ``MAILER'', or
     ``MAILER-DAEMON'' will be replied to (where these strings are case insen-
     sitive) nor is a notification sent if a ``Precedence: bulk'' or
     ``Precedence: junk'' line is included in the mail headers.  The people
     who have sent you messages are maintained as a db(3) database in the file
     .vacation.db in your home directory.

9.11	File and Directory Permission Default

umask(2) default is customizable.

	$FML_UMASK	for fml.pl
	$MSEND_UMASK	for msend.pl
	$UMASK	is used if neither $FML_UMASK nor $MSEND_UMASK is not defined.

9.12	Directory Permissions

複数の人が fmlserv と一緒に使う場合 fmlserv はメンバーリストを書き変え
る等のために group permission が必要です。
＃ そのために root process を作れば、そうでなくてもできなくはないはず
＃ ですが、root process を増やすことはやりたくないので

	$USE_FML_WITH_FMLSERV

変数はそれを意味するための内部変数ですが、普通は fml.pl が $DIR の隣に 
fmlserv という directory があるなら自動的に設定します。うまくいかない
ときは explicit に設定して下さい。それから $GID も fmlserv のために導
入された変数です。

9.13	sendmail 8.8 における check_* ルールセットについて

詳しくは CF を読んでね。sendmail 8.8 では様々なアクセス制御を容易にカ
スタマイズできるように以下のようなルールセットが用意されています。CFで
物足りない場合（そうはないとおもうぞ）はこれらを使ってごりごり 
sendmail.cf を書きます。

    check_mail          発信者のチェック
    check_rcpt          受信者のチェック
    check_relay         SMTP接続のチェック
    check_compat        発信者および受信者のペアについてのチェック

またSMTPコネクションの接続要求に対して tcp_wrapper のライブラリである
libwrap.a を使うように sendmail を compile しておけば、
/etc/hosts.allow などで制御できるようになります。NetBSD 1.3 などの最新
のOSではこれが配布されるソースでのデフォールトです。
ちなみに tcp_wrapper におけるデーモン名は sendmail です。

    Example:
    
    [/etc/hosts.allow]
    
    sendmail: mikoto.fml.org
    
    [/etc/hosts.deny]
    
    ALL: ALL
    
check_mail と check_rcpt はSMTP処理ルーチン srvrsmtp() 内でそれぞれ 
MAIL FROM: と RCPT TO: の命令の引数に対して適用されます。つまりそれぞ
れ SMTP で渡される MAIL FROM:のアドレス(発信者)と RCPT TO:のアドレス
(配送先)のチェックに使われます

check_relay はSMTPコネクションが張られた時に適用されます。check_relay 
は validate_connection() で呼ばれ接続が成立した SMTPコネクションが接続
を許可されているホストからのものか？などについてチェックをします。
validate_connection() では tcp_wrapper 形式の制御も可能です(前述)。

check_compat は単純なチェックではなく送信者と受取人の組で判定をしなけ
ればならないような複雑な判定に使います。
check_compat は配送ルーチン deliver() で適用されメールの送り主と配送
先のペアについてSMTP translation だけでなく配送するメールの全てについ
て適用されます。

9.14	SMTP and Authentication

draft-myers-smtp-auth-11.txt (submitted to be Proposed Standard)
RFC2222 (SASL)

SASL: Simple Authentication and Security Layer

draft-hoffman-smtp-ssl-06.txt (SMTP over secured layer)

9.15	&system() function

system は perl の内部関数ではなく独自に書いた system を使っています。
何故かうまく動かない場合や、fork() がないNTなどでは perl 附属の 
system() を使わざるを得ない場合があります。デフォールトでは perl 附属
の system() を使っていません。

コマンドがうまく動かない場合に 

	$INSECURE_SYSTEM = 1;  (default 0)

という変数設定をして動くことがあるかもしれません。

なお NT では system() を使っています。

いずれの場合でもシンタックスチェックが事前に行なわれ、その後 system を
呼んでいます。

10	ライブラリ関数

ここでは、カスタマイズに役に立ちそうなライブラリ関数の説明をします。
とりあえずいきあたりばったりに選んで説明:-)

10.1	daemon (libutils.pl)

(4.4BSDにならって) 今のプロセスをデーモンにします。
＃4.4BSDのdaemon()には引数がありますが、まだそれをEmulateしていません

fml.pl から cron.pl を動かすんなら、これをつかうとうまくいくといいです
な:-)
＃4.3BSDでしか動作確認してないけど…
＃なにがうれしいって、mailq にのこらない:-)

本来の使い方は /dev/console とかから たちあげるときに

	&use('utils');
	&daemon;
	デーモンになってからする仕事；

みたいにすると &daemon; のところでTTYを切り放しSTDIN,STDOUT,STDERRを閉
じます。
＃注意：4.4BSDの setsid()は 新しいセッションをはじめること

例:

	$FML_EXIT_HOOK .= q#
		&use('utils');
		&daemon;
		exec("$LIBDIR/bin/cron.pl $DIR -a");
	#;

$NOT_USE_TIOCNOTTY を セットしないと、うまく daemonさんになってくれな
いかもしれませんが…
＃このへんの挙動はいまひとつわからない…

4.4BSD では setsid() ですが、そのへんの細かいところは省略…

10.2	Sendmail (libsmtp.pl)

SYNOPSIS
	&Sendmail($to, $subject, $body, @to);

	$to		送り先
	$subject	メールのsubject
	$body		メールの本文
	@to		$to 以外の複数の送り先アドレスを配列で

10.3	SendFile (libsmtp.pl)

SYNOPSIS
	&SendFile($to, $subject, $file, $zcat, @to);

	$to		アドレス
	$subject	メールのSubject
	$file		送るべきファイル
	$zcat		送るべきファイルがgzipしてある場合変換して送る
			1 zcatを実行
			2 uuencodeを実行
	@to		上以外の複数のアドレス

	実際には、$zcat	@to エントリは使ってませんが…
	＃いつ、第４エントリ以降をなくすか保証しない

10.4	NeonSendFile (libsmtp.pl)

複数のアドレスとファイルを一辺にハンドリングし、メールで送り返すための
インターフェイス

SYNOPSIS
	&NeonSendFile(*to, *subject, *files);

	@to		配送したいアドレスリスト
			一人分のアドレスを $to にいれて渡してもＯＫ
	$subject	メールのSubject
	@files		送りたいファイル（複数可能）

10.5	Addr2FQDN              (fml.pl)

SYNOPSIS:
	&Addr2FQDN($addr);

もし与えられた文字列($addr)が @ を含んでいない時は 

	$addr@$FQDN

に変換。@ を含んでいればそのまま返す。

10.6	AddressMatch           (fml.pl)
See also: address_manipulate 2.1 

SYNOPSIS:
	&AddressMatching($addr1, $addr2)

$addr1 と $addr2 が同じものかどうか調べる。

10.7	MailListMemberP        (fml.pl)

SYNOPSIS:
	&MailListMemberP($addr)

アドレスがメンバーファイルの候補(@MEMBER_LIST)の中にあるかどうかを調べ
る。もしあればそのファイル名を返す。

10.8	MailListActiveP        (fml.pl)

SYNOPSIS:
	&MailListActiveP($addr)

アドレスがメンバーファイルの候補(@ACTIVE_LIST)の中にあるかどうかを調べ
る。もしあればそのファイル名を返す。

10.9	Append2                (fml.pl)

SYNOPSIS:
	&Append2($string, $file)

appends $string to $file

10.10	AutoRegist             (libutils.pl)

SYNOPSIS:
	&AutoRegist(*Envelope);
	&AutoRegist(*Envelope, $string);

自動登録ルーチン。明示的に

	&AutoRegist(*Envelope, 文字列);

と呼び出すことで文字列を登録すべきアドレスにすることができる

10.11	ChangeMemberList       (libfml.pl)

$ADDR_CHECK_MAX(default 10) 回、アドレスチェックを厳しくしながら
&DoChangeMemberList(@_); を繰り返し適用する。つまりデフォールトでは３
段階までしかアドレスチェックをしないので

	fukachan@sapporo.iij.ad.jp

の iij.ad.jp までしか比べないが、それだけでは曖昧な場合は
４段階つまり sapporo.iij.ad.jp までアドレスをチェックする。

例:

	fukachan@iij.ad.jp
	fukachan@sapporo.iij.ad.jp

の両方がファイル中に現れる場合。	

10.12	ChangePasswd           (libcrypt.pl)

SYNOPSIS:
	&ChangePasswd($PASSWD_FILE, $addr, $new)

$PASSWD_FILE 中の $addr に対してのパスワードを $new にする。
なお、この時点でパスワード認証は終っていなければならない。

10.13	CheckMember            (fml.pl)

Go to 10.25

関数名を変更した。互換性のため残っている。

SYNOPSIS:
	 &CheckMember($addr, $list);

$list の中に $addr が現れるかどうかしらべる。

10.14	CmpPasswd              (libcrypt.pl)

SYNOPSIS:
	&CmpPasswd($encrypt, $plain-passwd)

etc/passwd 中の
	cryptがかかったパスワード ($encrypt)
と
	user が送り込んだ plain password ($plain-passwd)
を比較する

10.15	CmpPasswdInFile        (libcrypt.pl)

SYNOPSIS:
	&CmpPasswdInFile($PASSWD_FILE, $addr, $pass)

$PASSWD_FILE 中のアドレス $addr に対しパスワード $pass で認証できるか
否か？

10.16	Conv2mailbox           (fml.pl)

SYNOPSIS:
    &Conv2mailbox($from, *e)

$from の中の アドレス部分（ユーザ＠ドメイン 部分）だけを取り出す。
なお *e はあってもなくてもよい。

10.17	DecodeMimeStrings      (libMIME.pl)

SYNOPSIS:
	$s = &DecodeMimeStrings($s);

$s 中のMIME文字列を日本語へ変換する。関数の返り値が日本語化された文字
列である。

10.18	Flock                  (fml.pl)

SYNOPSIS:
	&Flock();

$FP_SPOOL_DIR へ対して flock(2) をかける。

なお $Timeout{'flock'} (default 3600) 秒後 SIGALRM が fml.pl へ返るよ
うに設定している。この時 $SIG{'ALRM'} で定義された関数が実行される。
標準は &TimeOut; が実行され、fml.pl はタイムアウトエラーで終る。

10.19	Funlock                (fml.pl)

$FP_SPOOL_DIR に対する flock(2) をはずす。

10.20	GetID                  (libfml.pl)

SYNOPSIS:
	&GetID;

$SEQUENCE_FILE の値を返す。

10.21	GetTime                (fml.pl)

SYNOPSIS:
	&GetTime;

localtime(); を実行し、フォーマットの違ういくつかの日付変数(グローバル)
を設定する。

    $Now = sprintf("%02d/%02d/%02d %02d:%02d:%02d", 
		   $year % 100, $mon + 1, $mday, $hour, $min, $sec);
    $MailDate = sprintf("%s, %d %s %d %02d:%02d:%02d %s", 
			$WDay[$wday], $mday, $Month[$mon], 
			1900 + $year, $hour, $min, $sec, $TZone);

    $CurrentTime = sprintf("%04d%02d%02d%02d%02d", 
			   1900 + $year, $mon + 1, $mday, $hour, $min);

10.22	Lock                   (fml.pl)

SYNOPSIS:
	&Lock;

	if $USE_FLOCK がセットされいるなら
		&Flock;
	else 
		liblock.pl で定義されている link() を使う
		UNIX V7 時代からあった懐かしいロックアルゴリズムを使う
		require liblock.pl;
		&V7Lock;

10.23	Log                    (fml.pl)

SYNOPSIS:
	&Log($s);

$s 文字列を日付とともに $LOGFILE に書き込む。

10.24	LogWEnv                (fml.pl)

SYNOPSIS:
	&LogWEnv($s, *e);

は

	&Log($s)
	$e{'message'} .= "$s\n";

です。$LOGFILE への書き込みと、&Notify で返されるfml Status Reportの
内容に $s を付け加える。

10.25	Lookup (fml.pl)

SYNOPSIS:
	 &Lookup($addr, $list);

$list の中に $addr が現れるかどうかしらべる。

10.26	MailListActiveP	(fml.pl)

SYNOPSIS:
	&MailListActiveP($address);

$address はメーリングリストのメンバーか否か？つまり認証のリストの中に
含まれているか？配送先とは限らないことに注意。返り値はそのアドレスを含
むファイル名かNULL

10.27	MailListMemberP	(fml.pl)

SYNOPSIS:
	&MailListMemberP($address);

$address はメーリングリストの配送リストに含まれているか？否か？
返り値はそのアドレスを含むファイル名かNULL

10.28	Mesg                   (fml.pl)

SYNOPSIS:
	&Mesg(*Envelope, $s);

&Notify で返される fml Status Reportの内容へ $s を付け加える。

	$Envelope{'message'} .= "$s\n";

10.29	NewSyslog              (libnewsyslog.pl)
See also: daily 6.4 

newsyslog(8) like function.

10.30	Notify                 (fml.pl)

SYNOPSIS:
	&Notify;

ようするに "fml Status report $ML_FN" を送り返している関数。

   宛先:	$Envelope{'message:h:to'} 
		もし未定義の場合は $Envelope{'Addr2Reply:'} が使われる
   宛先(複数):	$Envelope{'message:h:@to'} にアドレスリストを入れる。
   Subject:	$Envelope{'message:h:subject'}
		default は "fml Status report $ML_FN"

$PROC_GEN_INFO (default 'GenInfo') で生成されるヘルプメッセージをつけ
て、$Envelope{'message'} をユーザに送り返す。

また、$Envelope{'error'} があればそれを管理者へ送る。

この時のメールの最後に現れる「さようなら」メッセージには

	$GOOD_BYE_PHRASE	(good bye phrase)
	$FACE_MARK		(face mark)

で変更できます。また $FACE_MARK という変数もあります（謎）

	$GOOD_BYE_PHRASE = "\tBe seeing you!   ";
	$FACE_MARK	 = "(^^)P〜";

例2:	Episode 42(謎)
	$GOOD_BYE_PHRASE = &JSTR("\tヴェデル シーン   ");

10.31	RunHooks               (fml.pl)

SYNOPSIS:
	&RunHooks;

もし $FML_EXIT_HOOK があれば

	eval $FML_EXIT_HOOK

10.32	ExecNewProcess		(fml.pl)

もし $FML_EXIT_PROG が定義されていれば

	exec $FML_EXIT_PROG;

を実行する。

10.33	SecureP                (fml.pl)
See also: 9 

SYNOPSIS:
	&SecureP($request);

コマンド等のユーザからＭＬサーバへのリクエスト($request)が”安全と思わ
れる”シンタックスのみで表現されているかどうか？を調べる。例外処理をす
る場合は SecureP を呼び出す前にケースバイケースで処理するか 
%SECURE_REGEXP を定義する(リスクは自分で負うこと)。
See also: 9.2 

10.34	SendBackInOrder     (libfop.pl)

SYNOPSIS:
	&SendBackInOrder($returnfile, $total, $subj, $sleeptime, @to)

	$returnfile	tmp/uja のようなファイル
	$total		全部で何分割しているか？
	$subj		Subject: 
	$sleeptime	何分おきに配送するか
	@to		配送リスト

まとめ送りサーバ msend.pl や mget の中で使われている代表的なファイル送
り返し関数。

10.35	SocketInit             (libsmtp.pl)

SYNOPSIS:
	&SocketInit;

プロセス間通信をはじめる前にはこれを呼ぶ。libsmtp.pl の中にあるので、
普通はどこからでも呼べる。

10.36	TurnOverW0             (libnewsyslog.pl)

SYNOPSIS:
	&NewSyslog'TurnOverW0($LOG_MESSAGE_ID);#';

newsyslog を適用する。

上の例は $LOG_MESSAGE_ID に newsyslog を適用する。

10.37	Unlock                 (fml.pl)
See also: 10.22 

上述の Lock の逆をやる。

10.38	Warn                   (fml.pl)

SYNOPSIS:
	&Warn($subject, $body);

中身は

	&Sendmail($MAINTAINER, $subject, $body);

と同じ。つまり管理者宛のメールを出す。

10.39	WholeMail              (fml.pl)

SYNOPSIS:	
	&WholeMail;

元のメールをスペース３文字インデントしたものを返す。インデントはぱっと
見た時に明らかに本文の中で違う意味を示すようにするためである。エラーメー
ル等で使う場合が多いため、変なフォーマットにする等の小細工はせず単純な
インデントですませるべきであろう。エラーデバッグのためには、できるだけ
生のメールを管理者へフォワードするべきだと思う。

$MIME_CONVERT_WHOLEMAIL をセットした場合MIME逆変換をしたメールも付加さ
れるが、エラーメール等では変なメールもありうるため推奨しない。

10.40	eval                   (fml.pl)

SYNOPSIS:
	&eval($eval_string)

$eval_string を eval する。$COMPAT_FML15 を指定すると eval の前後で補
正コードが適用されfml 1.5 依然のデータ構造でもほとんど動くはずである。
＃完璧に補正できる保証はないと思う。

10.41	ipc                    (libutils.pl)

SYNOPSIS:
	&ipc(*ipc, *r);

プロセス間通信インターフェイス。
=
Interface of InterProcess Communication based on Berkeley Socket mechanism.

	$ipc{'host'}	相手のホスト
	$ipc{'serve'}	ポート (/etc/services)
	$ipc{'tcp'}	TCP/IP を宣言
	$ipc{'pat'}	構造体パターン
	@ipc		相手サーバへのINPUT文字列
	$r		答えはこの中に入り返される。

10.42	system                 (libutils.pl)

SYNOPSIS:
	&system($s, $out, $in, $read, $write)

$s 文字列を実行する。チェックメカニズムを除けば内容的にＯＳの提供する 
system(3) とほとんど変わらない。

その際

	$in ファイルから読み
	$outファイルへ出力

	$write ファイルハンドルから読みこみ
	$read ファイルハンドルへ書く

なお	

    /[\$\&\*\(\)\{\}\[\]\'\\\"\;\\\\\|\?\<\>\~\`]/

の文字列にマッチした場合 security のため system() は実行されない。

11	Porting to other Operationg Systems

11.1	Micro$oft NT 4.0

	$HAS_GETPWUID
	$HAS_GETPWGID
	$HAS_ALARM

の変数はOFFになります。U*ix ではデフォールトでONです。 
ライブラリによっては次の変数をセットしているものもあります。

	$COMPAT_WIN32 = 1;

11.2	sys/ Directory

fml.pl の次の行は

    if ($COMPAT_ARCH)  { require "arch/${COMPAT_ARCH}/depend.pl";}

Architecture 依存コードをロードするためのものです。
Architecture 依存は

	sys/OS/perlスクリプト

のように並び適宜ローディングされます。

Appendix A	変数名や関数名の名付け方の慣習について

Appendix A.1	関数名

Capital by default. There are exceptional cases.

□ 例外

◯ 関数オーバーロードをちょっと意図している風

use()
eval()
system()
daemon()

◯ mget3_*() 関数群

proc/libsendfile.pl:108:sub mget3 
proc/libsendfile.pl:334:sub mget3_SendingEntry
proc/libsendfile.pl:393:sub mget3_unlink
proc/libsendfile.pl:440:sub mget3_Init
proc/libsendfile.pl:472:sub mget3_Reset
proc/libsendfile.pl:483:sub mget3_Getopt
proc/libsendfile.pl:516:sub mget3_Search
proc/libsendfile.pl:587:sub mget3_SearchInArchive
proc/libsendfile.pl:687:sub mget3_MHExpand
proc/libsendfile.pl:704:sub mget3_V2search
proc/libsendfile.pl:738:sub mget3_V1search

◯ fml_local ユーザ定義関数の例題 
   これはユーザ定義関数なので、普通の意味での慣習には従っていない

libexec/fml_local.pl:689:sub sendback
libexec/fml_local.pl:725:sub getmyspool_nopasswd
libexec/fml_local.pl:740:sub getmyspool
libexec/fml_local.pl:799:sub getmyspool2
libexec/fml_local.pl:829:sub forward
libexec/fml_local.pl:874:sub discard{ 1;}
libexec/fml_local.pl:880:sub getback { &sendback(@_);}
libexec/fml_local.pl:884:sub getmyspool_pw { &getmyspool(@_);}

Appendix B	some debug information
Appendix B.1	ロードしていく様子の例 (配送の場合)

$LIBDIR, $DIR の初期化

316:        require 'libloadconfig.pl'; &__LoadConfiguration('__KERN__');
57:         require 'default_config.ph';
73:             require("$DIR/config.ph");
318:        require 'libsmtp.pl';               # a library using smtp
474:        if ($COMPAT_ARCH)  { require "sys/$COMPAT_ARCH/depend.pl";}
476:        if ($DUMPVAR) { require 'dumpvar.pl'; &dumpvar('main');}
477:        if ($debug)   { require 'libdebug.pl';}

	$FP_*_DIR の初期化

880:            require("module/$LANGUAGE/liblangdep.pl");
39:         require 'jcode.pl'; # not needed but try again
1363:       require 'libdist.pl';
768:        if ($CF_DEF && $RELAY_HACK) { require 'librelayhack.pl'; &RelayHack;}


		INDEX

/usr/bin/newsyslog                         ...   4.3 
access(2)                                  ...   9.8 
$ACTIVE_LIST                               ...   7.7 
@ACTIVE_LIST                               ...   8.4 
actives と members の違い                  ...   8.3 
actives ファイルのフォーマットと構造       ...   8.2 
Addr2FQDN                                  ...   10.5 
AddressMatch                               ...   10.6 
Address Spoofing                           ...   9.4 
Append2                                    ...   10.9 
AutoRegist                                 ...   10.10 
'Body'                                     ...   6.5 
$CFVersion                                 ...   3.3 
$CHADDR_KEYWORD                            ...   6.5 
ChangeMemberList                           ...   10.11 
ChangePasswd                               ...   10.12 
$CHECK_MESSAGE_ID                          ...   4.2 
CheckMember                                ...   10.13 
ClearEvent                                 ...   6.8 
CmpPasswd                                  ...   10.14 
CmpPasswdInFile                            ...   10.15 
$COMMAND_CHECK_LIMIT                       ...   6.5 
$COMPAT_ARCH                               ...   11.2 
$COMPAT_CF1                                ...   3.4 
$COMPAT_FML15                              ...   3.5 
$COMPAT_FML20                              ...   3.6 
$COMPAT_WIN32                              ...   11.1 
$COMPRESS                                  ...   5.4 
config.ph                                  ...   8.7 
$CONFIRMATION_FILE                         ...   7.7 
Conv2mailbox                               ...   10.16 
daemon()                                   ...   10.1 
DecodeMimeStrings                          ...   10.17 
$DEFAULT_MGET_SUBJECT (config.ph CFv2)     ...   5.2 
$DEFAULT_MGET_SUBJECT (obsolete)           ...   5.2 
$DENY_FILE                                 ...   7.7 
$DIR                                       ...   6.3 
$DIR/etc/passwd                            ...   8.6 
DNS Spoofing                               ...   9.3 
$DO_NOTHING                                ...   7.8 
$DUMPVAR                                   ...   7.9 
dumpvar.pl                                 ...   7.9 
Email アドレスの表現                       ...   9.6 
%Envelope                                  ...   7.3 
eval                                       ...   10.40 
ExecNewProcess                             ...   10.32 
$FACE_MARK                                 ...   7.8 10.30 
'flock'                                    ...   6.7 
Flock                                      ...   10.18 
flock(2)                                   ...   6.9 
$FLOCK_TIMEOUT(Obsolete)                   ...   6.7 
$FML	                                      ...   7.8 
fml.plと引数                               ...   6.3 
$FML_EXIT_HOOK                             ...   5.5 
fml process                                ...   6 
fml 設定ファイルのフォーマットと構造       ...   8 
$FP_SPOOL_DIR                              ...   7.1 
$FP_TMP_DIR                                ...   7.1 
$FP_VAR_DIR                                ...   7.1 
$FP_VARDB_DIR                              ...   7.1 
$FP_VARLOG_DIR                             ...   7.1 
$FP_VARRUN_DIR                             ...   7.1 
$FP_VARRUN_DIR/lockfile.v7                 ...   6.9 
Funlock                                    ...   10.19 
GetID                                      ...   10.20 
GetTime                                    ...   10.21 
$GID                                       ...   9.12 
$GOOD_BYE_PHRASE                           ...   10.30 
$GUIDE_CHECK_LIMIT                         ...   6.5 
$GUIDE_FILE                                ...   7.7 
$GUIDE_KEYWORD                             ...   6.5 
$GUIDE_REQUEST                             ...   7.8 
$HAS_ALARM                                 ...   11.1 
$HAS_GETPWGID                              ...   11.1 
$HAS_GETPWUID                              ...   11.1 
'Header'                                   ...   6.5 
$HELP_FILE                                 ...   7.7 
How to maintain the installed fml source   ...   8.7 
$INCLUDE_SIM_PATH                          ...   7.8 
$INDEX_FILE                                ...   7.7 
%INSECURE_REGEXP                           ...   9.2 
$INSECURE_SYSTEM                           ...   9.15 
InSecureP                                  ...   9.2 
ipc                                        ...   10.41 
ish                                        ...   5.15 5.16 
$ISH                                       ...   5.4 5.15 
$LHA                                       ...   5.4 5.15 
libcompat_cf1.pl                           ...   3.4 
libcompat_cf2.pl                           ...   3.4 
$LIBDIR                                    ...   6.3 
libnewsyslog.pl                            ...   4.3 
librfc1153.pl                              ...   5.14 
Lock                                       ...   10.22 
$LOCK_EX                                   ...   6.9 
$LOCK_FILE                                 ...   7.7 
$LOCK_NB                                   ...   6.9 
$LOCK_SH                                   ...   6.9 
$LOCK_UN                                   ...   6.9 
Log                                        ...   10.23 
$LOG_CONNECTION                            ...   9.3 
$LOG_MESSAGE_ID                            ...   7.7 
$LOGFILE                                   ...   7.7 
LogWEnv                                    ...   10.24 
lzh                                        ...   5.15 5.16 
$MAIL_LENGTH_LIMIT                         ...   5.7 
MailListActiveP                            ...   10.8 
MailListMemberP                            ...   10.7 
maintenance                                ...   8.7 
%MAKE_FML                                  ...   7.8 
$MAX_TIMEOUT                               ...   6.7 
@MEMBER_LIST                               ...   8.4 
$MEMBER_LIST                               ...   7.7 
members ファイルのフォーマットと構造       ...   8.1 
Mesg                                       ...   10.28 
$MESSAGE_ID_CACHE_BUFSIZE                  ...   7.7 
mget                                       ...   5 
mget3                                      ...   5.3 
&mget3_SendingEntry                        ...   5.5 
mget3 の送り返しプロセス                   ...   5.5 
%mget_list                                 ...   5.5 
$MGET_LOGFILE                              ...   7.7 
$MGET_MODE_DEFAULT                         ...   5.2 
$MGET_SEND_BACK_FILES_LIMIT                ...   5.8 
$MGET_SEND_BACK_SLEEPTIME                  ...   5.5 
$MGET_SUBJECT_TEMPLATE                     ...   5.2 
mget で3のデフォールトの変更               ...   5.2 
Micro$oft NT 4.0                           ...   11.1 
$MIME_CONVERT_WHOLEMAIL                    ...   10.39 
msednrc ファイルのフォーマットと構造       ...   8.5 
$MSEND_RC                                  ...   7.7 
%MSendOpt                                  ...   5.2 
NeonSendFile                               ...   10.4 
NewSyslog                                  ...   10.29 
&NewSyslog                                 ...   4.3 
newsyslog(8)                               ...   4.3 
@NEWSYSLOG_FILES                           ...   4.3 
$NEWSYSLOG_MAX                             ...   4.3 
$NOT_SHOW_DOCMODE (config.ph CFv2)         ...   5.2 
Notify                                     ...   10.30 
$NULL                                      ...   7.8 
$OBJECTIVE_FILE                            ...   7.7 
$OT_SHOW_DOCMODE (obsolete)                ...   5.2 
$PASSWD_FILE                               ...   8.6 
$PeerAddr                                  ...   9.3 
Precedence                                 ...   9.9 
$REJECT_ADDR                               ...   4.1 
$REJECT_ADDR_LIST                          ...   7.7 
RFC1153                                    ...   5.13 
&Rfc1153Custom                             ...   5.14 
RFC822                                     ...   9.6 
RFC934                                     ...   5.12 
$RPG_ML_FORM_FLAG                          ...   7.8 
RunHooks                                   ...   10.31 
%SECURE_REGEXP                             ...   9.2 
SecureP                                    ...   9.2 10.33 
SecurePの拡張: %INSECURE_REGEXP            ...   9.2 
SecurePの拡張: %SECURE_REGEXP              ...   9.2 
SendBackInOrder                            ...   10.34 
SendFile                                   ...   10.3 
Sendmail                                   ...   10.2 
sendmail -> fml 時の動作                   ...   6.2 
$SEQUENCE_FILE                             ...   7.7 
SetEvent                                   ...   6.8 
setsid()                                   ...   10.1 
$Sigarlm                                   ...   6.7 
site_init.ph                               ...   6.4 
sitedef.ph                                 ...   8.7 
sitedef.ph                                 ...   6.4 
SJIS (lha + ish / lha + uuencode)          ...   5.16 
$SLEEPTIME                                 ...   5.5 
smrsh.c                                    ...   9.7 
$SMTPLOG                                   ...   7.7 
SocketInit                                 ...   10.35 
struct envelope e;                         ...   7.3 
$SUMMARY_FILE                              ...   7.7 
SYN Flooding                               ...   9.5 
system                                     ...   10.42 
$TAR                                       ...   5.4 
Tick                                       ...   6.8 
$TMP_DIR                                   ...   7.6 
TurnOverW0                                 ...   10.36 
Unlock                                     ...   10.37 
$USE_FLOCK                                 ...   6.9 
$USE_FML_WITH_FMLSERV                      ...   9.12 
$USE_WARNING                               ...   5.6 
uuencode                                   ...   5.16 
$UUENCODE                                  ...   5.4 
vacation                                   ...   9.10 
$VARLOG_DIR/_smtplog                       ...   7.7 
version up                                 ...   8.7 
Warn                                       ...   10.38 
$WELCOME_FILE                              ...   7.7 
whoisと日本語の問題                        ...   9.2 
WholeMail                                  ...   10.39 
$ZCAT                                      ...   5.4 
ＭＬサーバの動作                           ...   6.1 
インストール後のメインテナンスとversion up   ...   8.7 
データ構造の初期化                         ...   7.4 
パスワードファイルのフォーマットと構造     ...   8.6 
メールのヘッダ                             ...   6.5 
メールのボディ                             ...   6.5 
ライブラリ関数                             ...   10 
ロックアルゴリズム                         ...   6.9 
関数名の Naming Convention                 ...   7.2 
変数の Naming Convention                   ...   7.1 
