[PREVIOUS CHAPTER]
 [NEXT CHAPTER]
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 エントリは使ってませんが…
	#いつ、第4エントリ以降をなくすか保証しない
10.4	NeonSendFile (libsmtp.pl)
複数のアドレスとファイルを一辺にハンドリングし、メールで送り返すための
インターフェイス
SYNOPSIS
	&NeonSendFile(*to, *subject, *files);
	@to		配送したいアドレスリスト
			一人分のアドレスを $to にいれて渡してもOK
	$subject	メールのSubject
	@files		送りたいファイル(複数可能)
10.5	Addr2FQDN              (fml.pl)
SYNOPSIS:
	&Addr2FQDN($addr);
もし与えられた文字列($addr)が @ を含んでいない時は 
	$addr@$FQDN
に変換。@ を含んでいればそのまま返す。
10.6	AddressMatch           (fml.pl)
../address_manipulate 3.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(@_); を繰り返し適用する。つまりデフォールトでは3
段階までしかアドレスチェックをしないので
	fukachan@sapporo.iij.ad.jp
の iij.ad.jp までしか比べないが、それだけでは曖昧な場合は
4段階つまり 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)
../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)
9.0
SYNOPSIS:
	&SecureP($request);
コマンド等のユーザからMLサーバへのリクエスト($request)が”安全と思わ
れる”シンタックスのみで表現されているかどうか?を調べる。例外処理をす
る場合は SecureP を呼び出す前にケースバイケースで処理するか 
%SECURE_REGEXP を定義する(リスクは自分で負うこと)。
../internals 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)
10.22
上述の Lock の逆をやる。
10.38	Warn                   (fml.pl)
SYNOPSIS:
	&Warn($subject, $body);
中身は
	&Sendmail($MAINTAINER, $subject, $body);
と同じ。つまり管理者宛のメールを出す。
10.39	WholeMail              (fml.pl)
SYNOPSIS:	
	&WholeMail;
元のメールをスペース3文字インデントしたものを返す。インデントはぱっと
見た時に明らかに本文の中で違う意味を示すようにするためである。エラーメー
ル等で使う場合が多いため、変なフォーマットにする等の小細工はせず単純な
インデントですませるべきであろう。エラーデバッグのためには、できるだけ
生のメールを管理者へフォワードするべきだと思う。
$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 文字列を実行する。チェックメカニズムを除けば内容的にOSの提供する 
system(3) とほとんど変わらない。
その際
	$in ファイルから読み
	$outファイルへ出力
	$write ファイルハンドルから読みこみ
	$read ファイルハンドルへ書く
なお	
    /[\$\&\*\(\)\{\}\[\]\'\\\"\;\\\\\|\?\<\>\~\`]/
の文字列にマッチした場合 security のため system() は実行されない。
[PREVIOUS CHAPTER]
 [NEXT CHAPTER]