                ヘッダの書き換え

------------------------------------------------------------
1	ヘッダのいろいろな操作
1.1	サブジェクトの書き換え
1.2	ヘッダフィールドの値をコピーする
1.3	ヘッダフィールドの値をある値に強制的にする
1.4	ヘッダフィールドを消す
1.5	ヘッダフィールドの値をそのまま通すようにする
1.6	コマンドの返事メールのヘッダの値を設定する
1.7	ヘッダを素通しする(デフォールト)
1.8	ヘッダの並び方
1.9	RFC2369 (たとえば list-post )

2	関連事項
2.1	ヘッダの値によって弾く

3	事例集
3.1	Reply-To: が携帯電話のあどれすで困る
3.2	fmlでのwelcomeメールのsubjectを日本語にする
3.3	登録のconfirmationメールのsubjectをいじる
3.4	Received: を残す
3.5	Date: Type ($DATE_TYPE)
3.6	コマンドの結果やユーザへのメッセージのヘッダのカスタマイズ
3.7	コマンドメールの結果のメールの Reply-To: を変更する
3.8	Subject Tags; Subject: に (Elena 100) などのタグをつける
3.9	Subject: の成形 ([Elena:ID] フォーマットを抜く) [obsolete]
3.10	TAGの [Elena:00001] の五桁の数字をＮ桁に変更
3.11	TAGの [Elena:00001] の 0 パディングをなくす
3.12	元々の Message-ID を配送に使う
3.13	ML 独自の Message-ID フォーマット
3.14	宇宙歴 (外国TVシリーズMLで使ってます:-)
3.15	一つのメーリングリストに複数の投稿用アドレス
3.16	X-ML-Info: の内容を指定する
3.17	To: の Rewriting 処理
3.18	NIFTY対策をするか?(参加者にNIFの人もいる, OBSOLETE?)
3.19	Errors-To:をつける
3.20	Replyのメールのサブジェクトを新しくする際にブラケットを外さない
3.21	Reply-To: を From: + $MAIL_LIST に設定する   
3.22	Reply-To: を From: + $MAIL_LIST に設定する(2)   
3.23	サポート用のＭＬ
3.24	毎日 TAG をリセットしたい(一日のMail数が 一目でも分かるように)
3.25	投稿された記事 Received: を X-Received: に

4	内部構造
4.1	ヘッダ・フィールドのフォーマット

5	ヘッダのカスタマイズをする関数群
5.1	ヘッダフィールドの内容の強制
5.2	ヘッダフィールドを元メールのままにする
5.3	ヘッダのフィールドを増やす or 減らす
5.4	特定のヘッダ・フィールドのコピー

Appendix A	事例
Appendix A.1	改造事例: Reply-To == MLで必要な時にはReply-Toを設定するコマンド
------------------------------------------------------------


1	ヘッダのいろいろな操作

fml はＭＬの記事やコマンドの結果を知らせるメールなどのヘッダのフィール
ドの並び変えや特定のフィールドの削除などを行なっています。FML 2.2 以降
のデフォールトは『Return-Receipt-To と Received を除き素通し』に設定さ
れています。ヘッダの一部を切ったり、付け加えるにはconfig.phに &DEFINE_
なんとか という関数呼びだしを設定して行ないます。

1.1	サブジェクトの書き換え

	$SUBJECT_TAG_TYPE	[elena:00100] みたいな部分の選択
See also: 3.8 

	$SUBJECT_TAG_FIGURE	       ↑これの桁数

	MENU -> HEADER_CONFIG -> SUBJECT_TAG_TYPE
	MENU -> HEADER_CONFIG -> SUBJECT_TAG_FIGURE

1.2	ヘッダフィールドの値をコピーする
See also: 5.4 

	&COPY_FIELD(コピー元, コピー先);
  例:

	&COPY_FIELD('Sender', 'X-Sender');

1.3	ヘッダフィールドの値をある値に強制的にする
See also: 5.1 

	&DEFINE_FIELD_FORCED(フィールド名, 値);
  例:

	&DEFINE_FIELD_FORCED("reply-to", "$From_address, $MAIL_LIST");

1.4	ヘッダフィールドを消す
See also: 5.3 

	&DELETE_FIELD(フィールド名);
   例:

	&DELETE_FIELD('X-Uja');

デフォールトで $PASS_ALL_FIELDS_IN_HEADER が定義されているので見知らぬ
ヘッダは素通りしていく。しかし特定のフィールドだけを消したい時に便利

1.5	ヘッダフィールドの値をそのまま通すようにする
See also: 5.2 

	&DEFINE_FIELD_ORIGINAL(フィールド名);
   例:

	&DEFINE_FIELD_ORIGINAL('reply-to');

1.6	コマンドの返事メールのヘッダの値を設定する
See also: 3.7 

	&DEFINE_FIELD_OF_REPORT_MAIL(フィールド名, 値);
   例:

	&DEFINE_FIELD_OF_REPORT_MAIL('Reply-To', "Your Reply-To Address");

1.7	ヘッダを素通しする(デフォールト)
See also: 4.1 

   $PASS_ALL_FIELDS_IN_HEADER = 1;

1.8	ヘッダの並び方
See also: 4.1 

@HdrFieldsOrder という配列

1.9	RFC2369 (たとえば list-post )

$USE_RFC2369 = 1;

XXX: fml 4.0 ではデフォールトで on

2	関連事項

2.1	ヘッダの値によって弾く

これはヘッダの書き換えではなく、フィルタリングルールを拡張する命令。
詳しくはフィルタリングの章を参照してください。
例: subject にいかがわしい文字列があったら弾く

   &DEFINE_FIELD_PAT_TO_REJECT('subject', '/FREE|SEX|ADULT|XXX/');

3	事例集

3.1	Reply-To: が携帯電話のあどれすで困る

Q: 携帯電話から送られるメールで Reply-To: が携帯電話のアドレスのために
配送されたメールが Reply-To: ＭＬになりません。

A: 『常に強制的に Reply-To: ＭＬにしてしまう』ことで解決になるのなら

/var/spool/ml/elena/cf (PATHは適当によみかえてください) の 
LOCAL_CONFIG という行の後に

   &DEFINE_FIELD_FORCED('reply-to', $MAIL_LIST);

と書いて config.ph を作り直して下さい。作り直すのは例えば
   % cd /var/spool/ml/elena/cf
   % makefml update-config.ph elena

3.2	fmlでのwelcomeメールのsubjectを日本語にする

fml-support: 07219

ＭＬのHOMEにあるcfというファイルの最後(LOCAL_CONFIGという行より後)に

$START_HOOK = q#

	&use('MIME');
	$WELCOME_STATEMENT  = "ようこそここへ、うふふ";
	$WELCOME_STATEMENT  = &STR2EUC($WELCOME_STATEMENT);
	$WELCOME_STATEMENT  = &mimeencode($WELCOME_STATEMENT);

#;

と呪文を書いておいて、その場所で

make config.ph

で config.ph をつくりなおす

3.3	登録のconfirmationメールのsubjectをいじる

   "Subscribe confirmation request $ML_FN";

のような subject を自由にカスタマイズするのはちょっと面倒です。という
のは状態によってさまざまなsubjectに変わるので、それは今関数のなかに埋
め込まれてしまっています。

XXX 本来は messages/$LANGUAGE/ に押し出して外のファイルから定義を
XXX 変更できるようににするべきでしょうね。外側からそのてのフレーズをい
XXX じれるようにする作業はエラーとかは一通り終ってるけどそれ以外は...

例: 現状ではたぶんこんなんをかかないといけないす( not tested )

$CONFIRM_REPLAY_SUBJECT_FUNCTION = 'myGenConfirmReplySubject';

sub myGenConfirmReplySubject
{
    local(*e, *cf, $mode) = @_;
    local($s);

    if ($debug_confirm) {
	local(@c) = caller;
	&Log("GenConfirmReplySubject<$c[2]>: $mode") if $mode ne 'Default';
    }

    if ($mode eq 'Default') {
	$s = "Subscribe request result $ML_FN";
    }
    elsif ($mode eq 'Confirm::Confirmed') {
	$s = $CONFIRMATION_WELCOME_STATEMENT || $WELCOME_STATEMENT;
	# $s = "Newly added $From_address $ML_FN";
    }
    elsif ($mode eq 'Confirm::Error') {
	$s = "Subscribe with confirmation error $ML_FN";
    }
    elsif ($mode eq 'Confirm::GenPreamble') {
	$s = "$ML_FN登録の確認";
	$s = &STR2EUC($s);
	# $s = "Subscribe confirmation request $ML_FN";
    }
    elsif ($mode eq 'IdCheck::syntax_error') {
	$s = "Subscribe confirmation errror $ML_FN";
    }
    elsif ($mode eq 'Confirm::expired') {
	$s = "Subscribe confirmation expired $ML_FN";
    }
    elsif ($mode eq 'BufferSyntax::Error') {
	$s = "Subscribe confirmation errror $ML_FN";
    }
    elsif ($mode eq 'BufferSyntax::InvalidAddr') {
	$s = "Subscribe confirmation errror $ML_FN";
    }
    else {
	&Log("GenConfirmReplySubject: unknown mode [$mode]") if $debug_confirm;
	"Subscribe request result $ML_FN";
    }
}

3.4	Received: を残す

FML 2.2 以降では

    $SKIP_FIELDS  = 'Return-Receipt-To';

です。makefml configのメニューにあります(中身はこれ)。
＃2.1 では子文字じゃないとだめかも unshift(@HdrFieldsOrder, 'received');
＃この場合一行だけ Received ではなく received になってしまってちょっ
＃と情けないかも知れませんが…
＃RFC822 としては大文字小文字は関係ないので問題はない。カッコ悪いだけ;-)

歴史的に「サーバで受けたところまではOKなんだから、管理者が責任を持って、
ユーザにはMLサーバからユーザまでの配送分を見せれば十分だろう(余計なも
のは見せてもらわない方が幸せだろう)」という思想に基づき、デフォールト
では Received: はつけていません。またそれは too many hops によるエラー
を避けるためにも有効です。

念のためログを取るためには

	&DEFINE_MODE("stdinlog");

というモード指定があります。これは入力を日毎にログファイル(var/logの下)
に残しておきます(溜る一方なので注意してね)。

なお Posted: (user が出した時間)と Date: (サーバが配送した時間) の違い
を見るとサーバにたどり着くまでの時間差(Network 的にどのくらい遠いか?)
がわかります。
See also: 3.5 
See also: 3.5 

FYI: fml-support's ML Count: 01816, 01821 for the discussion

3.5	Date: Type ($DATE_TYPE)

fml 2.2 の $DATE_TYPE のデフォールト値は original-date 、
fml 2.1 は received-date です。

	未定義ならそのまま(互換性のため) received-date と同じになる

	original-date
		Date:	
		Posted: なし

	received-date
	received-date+posted
		Date:	FMLがメールを受けとった時間
		Posted:	元のメールそのままのDate:

	received-date+x-posted
		Date:	FMLがメールを受けとった時間
		X-Posted:	元のメールそのままのDate:

	received-date+x-original-date
		Date:	FMLがメールを受けとった時間
		X-Original-Date: 元のメールそのままのDate:

	distribute-date
	distribute-date+posted
		Date:	FMLがメール配送を始めた時間
		Posted:	元のメールそのままのDate:

	distribute-date+x-posted
		Date:	FMLがメール配送を始めた時間
		X-Posted:	元のメールそのままのDate:

	distribute-date+x-original-date
		Date:	FMLがメール配送を始めた時間
		X-Original-Date:	元のメールそのままのDate:

distribute-date は Date: と X-Mail-Count: が同じ順番になるためのもので
す。ださいMUAでソートする時だけは便利という説があります。

3.6	コマンドの結果やユーザへのメッセージのヘッダのカスタマイズ
See also: internals 7 

コマンドの結果やユーザへのメッセージのメールヘッダは

	$Envelope{'GH:field:'} 

で変更できます。GH というキーワードなのは SMTP Library の 
GenerateHeader() という関数内で使われるためです。ヘッダフィールドの並
び順は @HdrFieldsOrder の順番です。

Example:

コマンドの結果のメールの From: を特定のアドレス(および signatureつき等)
に変えたい場合。なお通常は From: は $MAINTAINER です。

	$Envelope{'GH:From:'} = "uja@aoi.chan.panic (AOICHAN PANIC)";

From: $MAINTAINER に限っては $MAINTAINER_SIGNATURE で signature をつけ
ることはできますが、まぁ形を気にするなら↑の方法で直接定義した方がより
よいでしょう。Dynamic に補正する必要がある場合は 
$REPORT_HEADER_CONFIG_HOOKで定義するとよい。
See also: hooks 3.11 

3.7	コマンドメールの結果のメールの Reply-To: を変更する

	&DEFINE_FIELD_OF_REPORT_MAIL('Reply-To', "Your Reply-To Address");

は次の設定と同じです。@HdrFieldsOrder 内で定義されているフィールドに対
して設定できます。

	$Envelope{'GH:Reply-To:'} = "Your Reply-To Address";

where the field is one of fields defined in @HdrFieldsOrder.
Backward compatibility で残っている変数が

	$FORCE_COMMAND_REPLY_TO = "address-you-want-to-use";

です。実際には $Envelope{'GH:Reply-To:'} への代入と全く同じです。

3.8	Subject Tags; Subject: に (Elena 100) などのタグをつける

FMLのデフォールトのデザインポリシーは「Subject: はいじらない。本来メー
ルソフトが好きな形にフォーマットするものをサーバ側でフォーマットを押付
けるべきではない」「有効に使いもしないのに Subject:の本体の情報を減ら
すタグはつけるべきではない」というものです。
＃注意：この問題は本来はメールインターフェイスプログラムが賢いか？
＃否か？という問題に還元されるべきものです。

Subject: にタグをつける時は$SUBJECT_TAG_TYPE という変数にタイプを設定
します。ちなみに makefml config で設定できます。

  $SUBJECT_TAG_TYPE		Subject: での形

	TYPE    Subject Example

		Subject: 	 	(DEFAULT, FML recommends this)
	(:)	Subject: (Elena:100)
	[:]	Subject: [Elena:100]	(hml 1.6 compatibility)
	( )	Subject: (Elena 100)
	[ ]	Subject: [Elena 100]
	(,)	Subject: (Elena,100)
	[,]	Subject: [Elena,100]
	()	Subject: (Elena)
	[]	Subject: [Elena]
	(ID)	Subject: (100)
	[ID]	Subject: [100]

[解説]
設定すると config.ph の中では次のような形に設定されています

	$SUBJECT_FREE_FORM = 1;
	$BEGIN_BRACKET     = '(';
	$BRACKET           = 'Elena';
	$BRACKET_SEPARATOR = ' ';
	$END_BRACKET       = ')';
	$SUBJECT_FREE_FORM_REGEXP = "\\($BRACKET \\d+\\)";

と定義すると (Elena 100) の形になり、Reply のメールの (Elena 99) をは
ずし新しい (Elena 100) をつけるようになります。

Another example: Subject: [Elena 100]

	$SUBJECT_FREE_FORM = 1;
	$BEGIN_BRACKET     = '[';
	$BRACKET           = 'Elena';
	$BRACKET_SEPARATOR = ' ';
	$END_BRACKET       = ']';
	$SUBJECT_FREE_FORM_REGEXP = "\\[$BRACKET \\d+\\]";

[捕捉]
$CFVersion 3 以前にあった $SUBJECT_HML_FORM は config.ph が CFVersion
3 以前のものだと判定された場合は内部で$SUBJECT_TAG_TYPE = "[:]"; へ変
換されます。現在の設定ではすでに無効な変数です。

3.9	Subject: の成形 ([Elena:ID] フォーマットを抜く) [obsolete]

[backward compatible, obsolete]
歴史的意味しかないので古いconfig.phを使っているならともかく、
新たに使うことはないはずです(使わないように)。

	$STRIP_BRACKETS = 1;

とすると Subjectから [ML:fukachan] みたいな部分をカットする。これは 
Subject: [Elena:ID] の形で配送するための前処理です。

3.10	TAGの [Elena:00001] の五桁の数字をＮ桁に変更

	$SUBJECT_FORM_LONG_ID (5; the number > 1)

はSubject:のTAGの数字部分の桁数を定義する。5(桁)がデフォールトだが 
$SUBJECT_FORM_LONG_ID 桁にする。$SUBJECT_FREE_FORM 使用時に有効な変数。
2 以上

注意:
かつて

	５桁がデフォールトだが $HML_FORM_LONG_ID 桁にする。
	$SUBJECT_HML_FORM = 1; の時にのみ有効。

という設定もありました。現在では $SUBJECT_FORM_LONG_ID を使うべき。
$CFVersion 3 以前にあった $HML_FORM_LONG_ID は config.ph が CFVersion
3 以前のものだと判定された場合は内部で $SUBJECT_FREE_FORM_LONG_ID; へ
代入変換されます。現在の設定ではすでに無効な変数です。

3.11	TAGの [Elena:00001] の 0 パディングをなくす

	$SUBJECT_FORM_LONG_ID = -1;

[注意] 昔は
	$HML_FORM_LONG_ID = -1;
も有効でしたが、今はありません。

3.12	元々の Message-ID を配送に使う

	$USE_ORIGINAL_MESSAGE_ID = 1; (default)

とすると元々メールにあった Message-ID を保存してヘッダにつけます。
これがデフォールトの挙動です。

References: fml-support ML's Count: 02687 あたりを参照

    References: fml-support: 02687
    
    original で妙な pattern の Message-ID を使われてて、ちゃんと detect で
    きないとかあると嫌ね＃そうそうあるとはおもえないのだが
    
    という可能性もある一方 ＃ばぐってるperlとかね〜
    
    fml 自体がつける場合、キャッシュテーブルの有効な大きさが半分になってし
    まふというのがあるので、元々を使う方が有効な大きさは増える。
    ループが発生する場合にどのくらい未来まで世界線をたどればいいのかは不明
    なので統計的な議論はできない。
    
    自分が自分に送るとかそういうのなら一瞬でループにはいるのでまず間違いな
    く検出するはずという場合が多いという仮定が正しいならどちらのやり方でも
    大差はないはず
    
    という論理になるような気がする。

true ?

3.13	ML 独自の Message-ID フォーマット
See also: hooks 3.2 

これは
	&DEFINE_FIELD_FORCED('Message-Id', "適当なID");
で解決ですが。HOOKを使うやり方も書いておきます。

Message-ID: uja@aoi.chan.panic は次のように config.ph にでも書けば 
$body の内容が @HdrFieldsOrder 中の : body: で展開されます。そのため
HOOKを使うなら @HdrFieldsOrder 中の : body: を切ってはいけません。

&DEFINE_FIELD_FORCED('Message-Id', "uja$$\@aoi.chan.panic");

は次と同じ

$HEADER_ADD_HOOK = q#
   $body .= "Message-ID: uja@aoi.chan.panic\n";
#;

Another Example:
Message-ID: <19950518.01905.Elena.Lolobrigita@Baycity.jp>

$HEADER_ADD_HOOK = q#
   $body .= "Message-ID: ".
	sprintf("<%4d%02d%02d.%05d.%s>\n", 1900 + $year, $mon + 1, $mday, $ID, 
	"Elena.Lolobrigita@Baycity.jp");
#;

3.14	宇宙歴 (外国TVシリーズMLで使ってます:-)

config.ph で $APPEND_STARDATE = 1; とすると宇宙歴がつきます:-)

	Date: Fri, 19 May 95 22:31:09  JST
	From: "No.6 Fukachan" <fukachan@phys.titech.ac.jp>
	Subject: Re: Nantonaku Leonard Nimoy 
	To: enterprise@phys.titech.ac.jp (Foreign TV Series ML)
	X-ML-Name: Prisoner

	…body…

みたいになります。スタートレックFAQ に C program がのっていますが、
libstardate.pl はその perl 版です。

3.15	一つのメーリングリストに複数の投稿用アドレス

何の意味があるのかは聞かないでください(笑)
例:
Elena@phys.titech.ac.jp というMLで

	Elena@phys.titech.ac.jp
	Anna@phys.titech.ac.jp

の両方を投稿可能にする。設定したいアドレスを config.ph で 
@MAIL_LIST_ALIASES という配列にずらずら書いて下さい。

  @MAIL_LIST_ALIASES = ('Elena@phys.titech.ac.jp', 
			'Anna@phys.titech.ac.jp'
		    );

なおHOOKの設定はもう必要ありません。&FixHeaders の中で書き換えは行なわ
れます。

その複数のアドレスを(ループチェックに使うために) @MAIL_LIST_ALIASES が
必要です。配列の先頭は $MAIL_LIST です。

こうすると Elena になげても Anna に投げても同じＭＬと見なし、

	$MAIL_LIST 

をその投げた方のアドレスに設定します。その副作用として

	To: と Reply-To:

がそのアドレスになります。

注意： @PLAY_TO, $Playing_to は昔の変数名です。この変数は 
compatibility のため自動的に @MAIL_LIST_ALIASES に代入されます。
＃ libcompat.pl にBackward compatibility のためのコードがありますが…

3.16	X-ML-Info: の内容を指定する

	&DEFINE_FIELD_FORCED('x-ml-info', "書きたいこと");

で強制的に指定すれば良いでしょう。一応昔風に変数

	$X_ML_INFO_MESSAGE

で指定した内容を優先して X-ML-Info: につけて配送できるようにもなってい
ます。そうでない場合はモードによって適当に作られた user friendly な内
容が付け加えられます。

3.17	To: の Rewriting 処理

2.1A の途中(config.ph CFVersion: 3.2)から To: Cc: は元のメールをそのま
ま通しています。2.2 のデフォールトは素通しです。

可読性のため、To: フィールドは $MAIL_LIST が展開され、常にＭＬのアドレ
スが出るようにすることもできます。makefml config ML で変更できます。

本来は書く人が気をつけるべきものであってＭＬサーバが気にするべきもので
はないでしょう。でも世の中わけ分からん人が多いので、apparent-to: になっ
ていて見辛いとか一体どうしてこのＭＬに来たメールなの？とかよくわからな
いメールのために常に To: $MAIL_LIST をつけることが可読性のためにもよい
とおもいますが…

現在は $REWRITE_TO が
	値	挙動
	0 	素通し (FML 2.2 default)

	1 	To: に $MAIL_LIST が含まれていればOK
		To: には $MAIL_LIST が含まれていない場合は
			To: $MAIL_LIST,
			    元の To: 

		にする (FML 2.1 default)。

	2 	To: $MAIL_LIST に強制する。
		To: の元々の内容は失われる。

To: Cc: というのは人間がメールを書く時の単なる便宜上のもので、配送手段
の SMTP としてはなんら区別はしていません。ですから、情報を落さず、To: 
は可読性のために $MAIL_LIST としています。

[蛇足] なお、To: Cc: の中に重複して現れるアドレスには普通それらを一つ
にまとめて一通分のみが配送されます。だから複数あっても気にしないでね

＃注意：なお、$NOT_REWRITE_CC は obsolete にしました

3.18	NIFTY対策をするか?(参加者にNIFの人もいる, OBSOLETE?)

注意: もう必要ないらしい

	$USE_ERRORS_TO = 1;

とすると Errors-To: をつけます。$AGAINST_NIFTY も同じ意味でしたが 
$CFVersion 3 ではなくなりました。

NIFTY は非常識にも、Errors-to という時代おくれの部分しかみてないので;_;、
config.ph あたりで

	$AGAINST_NIFTY = 1

とするとメール本文に

	Errors-To: $MAINTAINER

がつきます。これで NIFTY からのエラーメールが $MAINTAINER に返るように
なってくれます。後向きな解決法ですが;_;。
前向きなのは、みんなで文句をいって直させることです。
＃でも、僕はアカウントをもってない;_;。アカウントを持ってる人が一年く
らいいいつづけないとだめなんだろうなぁ（はぁ）

なお、$ERRORS_TO で Errors-To: の部分は $MAINTAINER から変更できます。

3.19	Errors-To:をつける

RFC1123 に逆らって Erros-To: をつけるなら $USE_ERRORS_TO = 1; 
$USE_ERRORS_TO = 1; if you append Errors-To:.

3.20	Replyのメールのサブジェクトを新しくする際にブラケットを外さない

例: (Elena 100) Re:(Elena 99) xxxxxx のままにしてしまう

$SUBJECT_TAG_TYPE を使わず、なおかつ $SUBJECT_FREE_FORM_REGEXP = $NULL;

	$SUBJECT_TAG_TYPE = "";
        $SUBJECT_FREE_FORM = 1;
        $BEGIN_BRACKET     = '(';
        $BRACKET           = 'Elena';
        $BRACKET_SEPARATOR = ' ';
        $END_BRACKET       = ')';
	$SUBJECT_FREE_FORM_REGEXP = $NULL;

と定義しておくと外す動作ではずせなくなる。
＃正確には(Elena 100)にマッチしなくなるだけなので、ちょっと違う

もしくは全然違う正規表現にしてマッチしないようにしておいても同様です。

注意としては $SUBJECT_TAG_TYPE も併用して差分だけ書いてはいけません。
$SUBJECT_TAG_TYPEを定義するとはfml が起動して config.ph をよんだ後に動
的に上の設定をしているので config.ph の設定では単純に上書きできません。

3.21	Reply-To: を From: + $MAIL_LIST に設定する   

$START_HOOK = q#
      &DEFINE_FIELD_FORCED("reply-to", "$From_address, $MAIL_LIST");
#;

You need to use a hook since From: address is dynamic variable, so
cannot define static setting in config.ph.

3.22	Reply-To: を From: + $MAIL_LIST に設定する(2)   

fml-support: 06240

○ やりたいこと

   if メンバー以外からの投稿
	Reply-To: From:のアドレス, メーリングリスト
   else
	Reply-To: メーリングリスト	

○ config.phの書き換えだけでうまくいくのでしょうか？

変数のon/offという意味なら no です。
HOOKを書いていいなら yes です。

config.ph は単なるperlのプログラムです。fmlのあちこちには hook をはし
らせることができます。複雑な操作を全部変数にしているときりがないので
ある程度以上はHOOKでおこなうことで、設定ファイルをfml本体とは分けて保
守するというというデザインになっています。
＃Emacs みたいなもんだとおもってくれればOK

$START_HOOK =q%
   if (&MailListMemberP($From_address)) {
	&DEFINE_FIELD_FORCED("reply-to", $MAIL_LIST);
   }
   else {
	&DEFINE_FIELD_FORCED("reply-to", "$From_address, $MAIL_LIST");
   }
%;

3.23	サポート用のＭＬ

Q:

このＭＬで、問い合わせへの返事＋スタッフ間の連絡で兼用
しています。

(1) 誰でも投稿できる(投稿だけ)。
(2) 配信されたメールに対して、
   (A)「ＭＬ加入者への返信」と
   (B)「問い合わせた人＋ＭＬ加入者への返信」
  を簡単に使い分けられるようにします。

そこで Reply-To を残したまま CC: に元メールの From: をいれておきたい。
そうすると(名称はメールソフトによるが)「ふつうに返信」で (A)、「全員に
返信」で (B) が実現できる。

答え:

$SMTP_OPEN_HOOK = q#
    if ($Envelope{'h:Cc:'}) {
        &DEFINE_FIELD_FORCED('Cc', 
		$Envelope{'h:Cc:'}. ", ". $From_address );
    } else {
        &DEFINE_FIELD_FORCED('Cc', $From_address);
    }
#;

注意: この場合のポイントは HOOK を使うことです。使わずに書くと 
      config.ph が評価される時に $From_address の値がまだ不定なのです。

3.24	毎日 TAG をリセットしたい(一日のMail数が 一目でも分かるように)

例えば0:00を境に
   Subject: [elena 00100] の番号を自動的に 
   Subject: [elena 00000] にしたい

/var/spool/ml/elena 以下の seq, summary, log, spool などを全部初期かし
てしまうしかないです。

解答例: このプログラム(shell script)を毎日夜12時にまわす

   #!/bin/sh

   ml=elena
   date=`date -u +%C%y%m%d`

   /usr/local/fml/makefml lock $ml 60 &

   cd /var/spool/ml/$ml || exit 1

   for file in seq spool summary log
   do
       if [ -f $file ];then
          # mv $file $file.$date
          cp  $file $file.$data
         cp /dev/null $file
       fi
   done

3.25	投稿された記事 Received: を X-Received: に

Q: 	投稿された記事 Received: を X-Received: に
	そしてコピーしてその元の Received: は消す。

A:

	&COPY_FIELD('Received', 'X-Received');
	$SKIP_FIELDS = 'Received|Return-Receipt-To';

[結果]

 Received: by hikari.fml.org (8.9.3/3.4W6+Hikari-2.1) with ESMTP id XAA17996 for <fukachan@sapporo.iij.ad.jp>; Wed, 6 Oct 1999 23:29:52 +0900 (JST)
 Received: from beth.fml.org (localhost.sapporo.iij.ad.jp [127.0.0.1])
 	by beth.fml.org (Postfix) with ESMTP id 1CE0EA6837
 	for <fukachan@fml.org>; Wed,  6 Oct 1999 23:29:52 +0900 (JST)
 X-Received: by hikari.fml.org (8.9.3/3.4W6+Hikari-2.1) with ESMTP id XAA17981 for <fukachan@sapporo.iij.ad.jp>; Wed, 6 Oct 1999 23:29:30 +0900 (JST)
 X-Received: by beth.fml.org (Postfix)
 	id 465B4A6838; Wed,  6 Oct 1999 23:29:30 +0900 (JST)
 X-Received: by beth.fml.org (Postfix, from userid 1106)
 	id 0DB1EA6837; Wed,  6 Oct 1999 23:29:29 +0900 (JST)
 Date: Wed,  6 Oct 1999 23:29:29 +0900 (JST)
 From: fukachan@fml.org (Ken'ichi Fukamachi)
 Reply-To: elena@fml.org
 To: fukachan@fml.org
 Message-Id: <19991006142929.0DB1EA6837@beth.fml.org>
 X-ML-Name: elena
 X-Mail-Count: 00207
 X-MLServer: fml 2.2; post only (only members can post)
 X-ML-Info: If you have a question, send e-mail with the body
 	"help" (without quotes) to the address elena-ctl@fml.org;
 	help=<mailto:elena-ctl@fml.org?body=help>
 Precedence: bulk
 Lines: 2

 test

 -- fukachan

4	内部構造

4.1	ヘッダ・フィールドのフォーマット
See also: internals 7 

fml は配送メールおよびコマンドの結果を知らせるメールなどのヘッダのフィー
ルドの成形を行います。またあらかじめ設定されたフィールドのみを通すよう
に設定できます。例えば、フィールドの並び順は @HdrFieldsOrder という変
数配列に従い、@HdrFieldsOrder に出てくるフィールドのみを通過させます。
X-Faces のようなうざったいフィールドは通さない などのようにです。

$PASS_ALL_FIELDS_IN_HEADER という変数を指定すると @HdrFieldsOrder にな
いフィールドも通過させます。@HdrFieldsOrder にないフィールドは入力の順
番でヘッダに現れます。2.2以降のデフォールトでは１です(素通し)。

	$PASS_ALL_FIELDS_IN_HEADER = 1; (path through, 1 is default)

* fml 2.1 is "0", fml 2.2 is "1".

注意: $SUPERFLUOUS_HEADERS は昔の名前です。
なお $PASS_ALL_FIELDS_IN_HEADER でも $SUPERFLUOUS_HEADERS でもどっちを
使ってもOKです。また makefml は自動的に変換します($CFVersion 3.2)。

ただし Received: と Return-Receipt-To: は切落とします($SKIP_FIELDS と
いう変数で定義されているフィールドは通さない)。この２つのフィールドを
通すには明示的に@HdrFieldsOrder に定義する必要があります。
Return-Recipient-To は当然として Received: は MAX HOP を越える場合に備
えてです。

フィールドの種類と順番に凝る場合:-)は @HdrFieldsOrder を config.ph 等
で定義しなおしてください。

@HdrFieldsOrder のデフォールトは (1998/08/10, 2.2BETA#1)

    @HdrFieldsOrder =	# rfc822; fields = ...; Resent-* are ignored;
	('Return-Path', 'Received',
	 'Date', 'Posted', 'X-Posted', 'X-Original-Date',
	 'From', 'Reply-To', 'Subject', 'Sender', 
	 'To', 'Cc', 'Errors-To', 'Message-Id', 'In-Reply-To', 
	 'References', 'Keywords', 'Comments', 'Encrypted',
	 ':XMLNAME:', ':XMLCOUNT:', 'X-MLServer', 
	 'XRef', 'X-Stardate', 'X-ML-Info', 
	 'X-Mailer',
	 ':body:', ':any:', 
	 'X-Authentication-Warning',
	 'Mime-Version', 'Content-Type', 'Content-Transfer-Encoding',
	 'Content-ID', 'Content-Description', # RFC2045
	 'Precedence', 'Lines');

のように定義されています。X-Authentication-Warning は PICKY_HELO_CHECK
(sendmail) 等で Security の Warning がつくので通すようにしました。

また @HdrFieldsOrder 中では

	:body:
	:any:
	:XMLNAME:
	:XMLCOUNT:

の特殊な変数が使われています。それぞれ

	:body:		$body を展開する場所
			$SMTP_OPEN_HOOK や $HEAD_ADD_HOOK 等で独自ヘッダを
			$body で定義した場合等に使われる(Backward Compatible)

	:any:		$PASS_ALL_FIELDS_IN_HEADER の時 @HdrFieldsOrder
			に明示的に現れないフィールドを展開する場所

	:XMLNAME:	$XMLNAME を展開する (X-ML-Name: フィールド)

	:XMLCOUNT:	$XMLCOUNT を展開する (X-Mail-Count: フィールド)

のような特殊な目的に使われます。これらは互換性の趣が強い例外処理です。

5	ヘッダのカスタマイズをする関数群

5.1	ヘッダフィールドの内容の強制

SYNOPSIS:
	&DEFINE_FIELD_FORCED('field', "field-contents");

@HdrFieldsOrder 内で定義されているフィールドに対し、フィールドの内容を
強制操作します。なお

	$Envelope{'fh:field:'} = "field-contents";

と同じです。
＃obsolete ですがコマンドラインの --fh:field="field-contents" と同じ

例: X-Ml-Info: の内容を"書きたいこと"に設定する。
	&DEFINE_FIELD_FORCED('x-ml-info', "書きたいこと");
	&DEFINE_FIELD_FORCED('x-ml-info', "ML Information");

5.2	ヘッダフィールドを元メールのままにする

SYNOPSIS:
	&DEFINE_FIELD_ORIGINAL('field');

@HdrFieldsOrder 内で定義されているフィールドに対し元々の値(MLサーバへ
入ってきた時のヘッダの値)にしておきたいフィールドを指定します。これは

	$Envelope{'oh:field:'};

と同じです。
＃obsoleteですが --oh:field  (コマンドライン)と同じ

例: To:, Cc:, Reply-To: を元の内容のままにする。

	&DEFINE_FIELD_ORIGINAL('to');
	&DEFINE_FIELD_ORIGINAL('cc');
	&DEFINE_FIELD_ORIGINAL('reply-to');

To: Cc: フィールドを元々の値のまま配送する。

5.3	ヘッダのフィールドを増やす or 減らす

&ADD_FIELD, &DELETE_FIELD という関数も用意しています。
例: X-Uja を付け加える。

	&ADD_FIELD('X-Uja');

Cc: フィールドを“つけない”なら

	&DELETE_FIELD('Cc');

注意: 96/11/2 $NOT_USE_CC を削除しました。@HdrFieldsOrder を直接いじる
か &DELETE_FIELD('Cc') を使って下さい。

ヘッダに現れる順番が重要な場合は @HdrFieldsOrder という配列を直接いじ
るしかありません。

例: 先頭に X-Some-Thing をつける

	unshift(@HdrFieldsOrder, 'X-Some-Thing');

5.4	特定のヘッダ・フィールドのコピー

@HdrFieldsOrder 内で定義されているフィールドに対し、

where the field is one of fields defined in @HdrFieldsOrder.

		&COPY_FIELD(field, new-field);
	Example:
		&COPY_FIELD('Sender', 'X-Sender');

Appendix A	事例

Appendix A.1	改造事例: Reply-To == MLで必要な時にはReply-Toを設定するコマンド

fml 2.x ではこのままではうごきません。参考までに収録しています。

    From:    Yuao Tanigawa <yuao@infonia.or.jp>
    X-ML-Name: fml-support
    X-Mail-Count: 01249
    
    メール本文の最初に、
    	# replyto myaddr@mydomain 
    
    と書いて、次の行から通常の文章を書いて投稿すれば、
    Reply-To にそのアドレスをセットして記事を配送します。
    
      うちのMLでは、今まで、Reply-Toのアドレスを強制的にはMLの
    アドレスに書き換えないようにしていたのですが、最近、いつも
    Reply-Toに自分のアドレスを書いて投稿する人とかいて、Reply-To
    にはアドレスを書かないようにと言うと、メールソフトの使い方
    とかよく知らなくて、Reply-Toのアドレスの設定方法とかも知ら
    ない人とかいたりして（学校とかでも周りの人とかも知らないら
    しい）、どうしようもなくなったので、Reply-Toには、強制的に
    MLのアドレスを書くようにしました。
      でも、必要なときにはReply-Toにアドレスが設定できると便利
    なので、以下のようにして、# replyto コマンドを使えるように
    してみました。
    
      config.phで、$SMTP_OPEN_HOOK には、
    
        $Envelope{'h:reply-to:'} = $Reply_to
                = $Envelope{'command:reply-to:'} || $MAIL_LIST;
    
    として、$COMMAND_HOOK には、
    
        if(/replyto/io) {
            &Log("Set Reply-To: $Fld[2]");
            $e{'command:reply-to:'} = $Fld[2];
            $e{'Body'} =~ s/#\s*replyto\s+\S+\n//io;
            &Distribute;
            last GivenCommands;
        }
    
    としました。ただし、この場合、$COMMAND_HOOK のクォートに、
    `#'記号が使えないです。
    
でもコマンドで実装しなくてもええやんか？メール本文の先頭に
Reply-To: address があったらそれを設定する。

$START_HOOK = q!
    local($pat) = '.*\s*reply-to:\s*';
    local($s);
    if ($Envelope{'Body'} =~ /^$pat(\S+)/i) {
	&DEFINE_FIELD_FORCED('reply-to', $s=$1);
        &Log("reply-to: <$s>");
	$Envelope{'Body'} =~ s/^$pat\S+\n//io;
    }
!;


		INDEX

[Elena:ID]の0パディングをしない            ...   3.11 
[Elena:ID]を抜く                           ...   3.9 
$APPEND_STARDATE                           ...   3.14 
$DATE_TYPE                                 ...   3.5 
&DEFINE_FIELD_FORCED('x-ml-info', "書きたいこと");   ...   3.16 
Errors-To:                                 ...   3.18 
--fh:field                                 ...   5.1 
$FORCE_COMMAND_REPLY_TO                    ...   3.7 
&GenerateHeader()                          ...   3.6 
GenerateHeader()                           ...   3.6 
'GH:field:'                                ...   3.6 
'GH:Reply-To:'                             ...   3.7 
@HdrFieldsOrder                            ...   4.1 
$HML_FORM_LONG_ID                          ...   3.10 3.11 
libstardate.pl                             ...   3.14 
@MAIL_LIST_ALIASES                         ...   3.15 
$MAINTAINER                                ...   3.6 
$MAINTAINER_SIGNATURE                      ...   3.6 
Message-ID                                 ...   3.12 
Message-ID の独自フォーマット              ...   3.13 
$NOT_USE_CC                                ...   5.3 
--oh:field                                 ...   5.2 
$PASS_ALL_FIELDS_IN_HEADER                 ...   4.1 
@PLAY_TO                                   ...   3.15 
$Playing_to                                ...   3.15 
Posted:(user が出した時間)とDate:(サーバが配送した時間)の差   ...   3.4 
Received: を残す                           ...   3.4 
replyto コマンド                           ...   Appendix A.1 
StarDate                                   ...   3.14 
STAR TREK                                  ...   3.14 
$STRIP_BRACKETS                            ...   3.9 
$SUBJECT_FORM_LONG_ID                      ...   3.11 
$SUBJECT_FORM_LONG_ID                      ...   3.10 
$SUBJECT_FREE_FORM                         ...   3.8 
$SUBJECT_TAG_TYPE                          ...   3.8 
Subjectから[Elena:ID]を抜く                ...   3.9 
$SUPERFLUOUS_HEADERS                       ...   4.1 
$USE_ERRORS_TO                             ...   3.18 
$USE_ORIGINAL_MESSAGE_ID                   ...   3.12 
$X_ML_INFO_MESSAGE                         ...   3.16 
XMLCOUNT                                   ...   4.1 
$XMLNAME                                   ...   4.1 
コマンドのREPLYメールのヘッダ              ...   3.6 
ヘッダ・フィールドのフォーマット           ...   4.1 
ヘッダのフィールドを増やす or 減らす       ...   5.3 
複数の投稿用アドレス                       ...   3.15 
