#!/usr/bin/perl

;# ↑ ◎ Perl5のパスを指定。このパスはプロバイダに確認。
;#
;#   電子会議室 [ミーティングルーム] ver.5.01 (Free)
;#   Copyright(C)1997-2001 WiS. All rights reserved.
;#

&ErrorSign if ($ENV{'QUERY_STRING'} eq 'error');
eval {

#-----------------------------------------------------------------------------#
# ここから初期設定（サーバーへの設置方法は同梱の'readme.txt'をご覧ください）  #
#-----------------------------------------------------------------------------#
#
#   ●印の項目は必ず変更してください。
#   ○印の項目は主にレイアウト関連です。基本的に変更不要です。
#   ◎印の項目はサーバー環境によって変更する必要があります。（1行目も含みます）
#
#  ・ ''内に記述しますが、'を入れたい場合は 中の'は \'にしてください。
#  ・ 行の頭に"#"を付けると、その行は無効になります。(コメントアウト)
#  ・ "$"、";"、"="等は間違って消さないようにしてください。エラーになります。
#  ・ 詳しくは本サイトの解説/FAQ等を参照してください。
#

# ○ 日本語文字コード (sjis／jis／euc)
$jcode = 'sjis';

# ◎ 入力形式（'POST'／'GET'）
#     * 送信して'Method not implemented..'等のエラーが出る場合は'GET'で試す。
#       'GET'の場合は文字制限があるため、長い文章等は途中で切れる場合がある。
$method = 'POST';


#---<パスについて>-------------------------------------------------------------
#
#  ・ パスとはサーバー内での場所です。httpで始まるURLとは違うものです。
#  ・ 相対パスとはスクリプトの場所を基準としたパスの指定です。
#      ../ => 1つ上のディレクトリ  ./ => 同じディレクトリ
#  ・ 絶対パスとはサーバー内の一番上のディレクトリを基準としたパスの指定です。
#      /usr/lib/sendmail  /home/foo/public_html/cgi-bin/script.cgi
#  ・ 仮想アドレスとはURLの一部分(ドメイン名以降)を指します。
#     http://www.domain.com/~foo/cgi-bin/script.cgi
#                          ^ ドメイン名の後のスラッシュ"/"以降の部分
#                             (/~foo/cgi-bin/script.cgi のこと)

# ○ 日本語変換ライブラリ"jcode.pl"のパス
require './jcode.pl';

# ○ CGI標準入出力ライブラリ"stdio.pl"のパス
require './stdio.pl';

# ○ データ格納用ディレクトリのパス
#     * このディレクトリのパーミッションは<777>or<707>にする
$DataDir = './data/';

# ○ データファイルのファイル名 (ファイル名であってパスではない)
#     * データを記録するファイル
$DataName = 'data.txt';

# ○ サーバー環境設定ファイルのファイル名 (ファイル名であってパスではない)
#     * パスワード等を記録するファイル。拡張子が"*.cgi"だが、CGIではない
$EnvName = 'env.cgi';

# ○ システム環境設定ファイルのパス
$SetupFile = './setup.ini';

# ◎ メール送信コマンドsendmailのパス
#     * メール送信関連機能を使用しない(できない)場合はコメントアウトする
$sendmail = '/usr/sbin/sendmail';

# ◎ ユーザーファイルのパス (ユーザー認証を使う場合のみ)
#     * 書き込み時にユーザー認証する場合のみ、ユーザーIDとパスワードを記録した
#       ユーザーファイルが必要となります。ユーザーファイルはhtpasswd等で生成で
#       きます。通常は設定する必要はありません。
$UserFile = 'user.txt';


#---<特殊な設定>---------------------------------------------------------------
#
#   通常は自動的にセットされるため設定不要。ただし、CGI-WRAP等を採用して
#   いるサーバー(interQ等)は、設定する必要がある。
#    * 設定した場合は、$の前のシャープ"#"を取り除く

# ◎ サーバーの名前 (通常設定不要)
#$ENV{'SERVER_NAME'} = 'www.domain.ne.jp';

# ◎ スクリプト(このファイル)の仮想アドレス (通常設定不要)
#$ENV{'SCRIPT_NAME'} = '/~foo/cgi-bin/sbbs.cgi';


#-----------------------------------------------------------------------------#
# 初期設定ここまで (以下、修正不要。変更した場合は動作未保証＆サポート対象外) #
#-----------------------------------------------------------------------------#

};
$Script   = $1 if ($ENV{'SCRIPT_NAME'} =~ /([^\\\/]+$)/);
Error('301 初期設定エラー',$@) if ($@);


#/*------------- 基本情報の設定 ---------------------------------------------*/

$SIG{'PIPE'} = $SIG{'INT'} = $SIG{'HUP'} = $SIG{'QUIT'} = $SIG{'TERM'} = "sigexit";

$Version  = 'Meeting Room/5.01';
$DataFile = $DataDir . $DataName;
$EnvFile  = $DataDir . $EnvName;

%STDIN    = stdio::QueryString(1,1,$jcode);

$Time = stdio::SetTime('yyyy/mm/dd hh:nn:ss');


$FlagFile   = $DataFile . '.flg';
$BackupFile = $DataFile . '.bak';

if ($STDIN{'mode'} eq 'setup'){
	SetupPassword();}

if (!-s $EnvFile){
	OutputPasswordSetForm();}

if (!$E{'Passwd'}){
	%E = ReadEnvFile($EnvFile);}

Error('100 ファイル未検出','設定ファイルが存在しません。') if (!-e $SetupFile);
open(FILE, $SetupFile) || Error('101 ファイル読込エラー','設定ファイルの読み込みができません。');
while (<FILE>) {
	if ($hereDocument) {
		if (/^\|$hereDocument\|/) {
			undef $hereDocument;
		} else {
			$S{$Key} .= $_;
		}
		next;
	}
	next if (/^#/ || /^\s*$/);
	s/\r|\n//;
	($Key,$Value) = split(/=/, $_, 2);
	$Key =~ s/\s|\t//g;
	if ($Key =~ /\./) {
		@Key = split /\./, $Key;
		if ($Key[0] ne '*' && $Script !~ /$Key[0]/) {
			undef @Key;
			next;
		} else {
			$Key = $Key[1];
			undef @Key;
		}
	}
	if ($Value =~ /^\s*"(.*)"\s*$/ || $Value =~ /^\s*'(.*)'\s*$/) {
		$Value = $1;
		$Value =~ s/\\\"/"/g;
		$Value =~ s/\\\'/'/g;
	} elsif ($Value =~ /\|(.+)\|/) {
		$hereDocument = $1;
		next;
	} else {
		$Value =~ s/\s|\t//g;
	}
	if ($Key =~ /\+$/) {
		$S{$Key} .= "\t$Value";
	} else {
		$S{$Key}  = $Value;
	}
}
close(FILE);

###############################################################################

$TimeNow   = stdio::SetTime($S{'TimeFormat'},$S{'TimeZone'});
$HTTP_USER_AGENT = substr($ENV{'HTTP_USER_AGENT'}, 0, 150);
$HTTP_USER_AGENT =~ s/&/&amp;/g;
$HTTP_USER_AGENT =~ s/"/&quot;/g;
$HTTP_USER_AGENT =~ s/</&lt;/g;
$HTTP_USER_AGENT =~ s/>/&gt;/g;
$REMOTE_HOST = $ENV{'REMOTE_HOST'};
$REMOTE_ADDR = $ENV{'REMOTE_ADDR'};
if ($REMOTE_HOST eq $REMOTE_ADDR || !$REMOTE_HOST) {
	$REMOTE_HOST = gethostbyaddr(pack('C4',split(/\./, $REMOTE_ADDR)),2) || $REMOTE_ADDR;
	$REMOTE_HOST = $REMOTE_ADDR if (!$REMOTE_HOST);
}

if (!$STDIN{'mode'} || $STDIN{'mode'} eq 'seek' || $STDIN{'mode'} eq 'treeview' || $STDIN{'mode'} eq 'listview'){
	$SearchJump = qq|<a href="#search" onClick="document.searchForm.keyword.focus();">検索</a>|;}

else{
	$SearchJump = qq|<a href="$Script#search">検索</a>|;}

$Menu = qq|<p><small>〔<a href="$Script?mode=form">新規投稿</a>〕〔$SearchJump〕〔<a href="$Script?mode=treeview">ツリー表\示</a>〕〔<a href="$Script?mode=listview">リスト表\示</a>〕〔<a href="$S{'HomeUrl'}">終了</a>〕〔<a href="http://www.ink.or.jp/~ink/technote/infor.cgi">試験稼動中の別の掲示板へ飛ぶ</a>〕</small></p>|;

#/*------------------- 処理別による条件分岐 -----------------------------------------*/

if ($STDIN{'mode'} eq 'form' || $STDIN{'res'}){
	OutputSubmitForm();}

elsif ($STDIN{'mode'} eq 'view'){
	SeeMessages();}

elsif ($STDIN{'mode'} eq 'setview'){
	OutputSetView();}

elsif ($STDIN{'mail'}){
	OutputSendMailForm();}

elsif ($STDIN{'mode'} eq 'sendmail') {
	SecretSendMail();}

elsif ($STDIN{'mode'} eq 'input') {
	OutputMessage();}

elsif ($STDIN{'mode'} eq 'seek')  {
	SearchMessages();}

elsif ($STDIN{'mode'} eq 'delete' || $STDIN{'mode'} eq 'deleteTree') {
	DeleteMessages();}

elsif ($STDIN{'mode'} eq 'form')  {
	OutuputSearchForm();}

else{
	print "Content-type: text/html\n\n";}

$STDIN{'mode'} = 'treeview' if ($STDIN{'mode'} ne 'treeview' && $STDIN{'mode'} ne 'listview');
if ($STDIN{'mode'} eq 'treeview') {
	@Record = stdio::ReadFile($DataFile, undef, undef, $E{'UseLock'});
	Error('110 排他制御中','只今混雑しています。時間をおいて再試行してください。') if ($Record[0] == -2);
	%FileHead = stdio::ReadData(split /\t/, $Record[0]);
	$FileHead{'Lines'} --;
	OutputTreeView() if ($Record[1]);

} else {
	@Record = stdio::ReadFile($DataFile, $STDIN{'start'}-1, $S{'PageMax'}, $E{'UseLock'}, 0, 1);
	Error('110 排他制御中','只今混雑しています。時間をおいて再試行してください。') if ($Record[0] == -2);
	%FileHead = stdio::ReadData(split /\t/, shift(@Record));
	$FileHead{'Lines'} --;
	OutputListView() if ($Record[0]);
}

print <<_EOF_;

<html>
<head>
<Title>$S{'Title'}</Title>
</head>
<body $S{'Body'}>
$S{'Header'}
$Menu
<hr noshade>
<h3>投稿されている記事が存在しません</h3>
<hr noshade>
<form action="$Script" method=$method><input type=hidden name=mode value=delete><input type=hidden name=adminMode value=1>
  <table border=1 cellpadding=3 cellspacing=0>
    <tr>
      <td>パスワード　<input type=password name=Passwd size=10 maxlength=16><input type=submit value="管理"></td>
    </tr>
  </table>
</form>
$S{'Footer'}
<h5 align=right><a href="http://www-power.net/" target=_top title="Produced by WEB POWER"><i>$Version</i></a></h5>
</body>
</html>

_EOF_

exit(0);


#/*------------- ツリー型表示 -----------------------------------------------*/

sub OutputTreeView {
	print <<_EOF_;

<html>
<head>
<title>$S{'Title'}</title>
</head>
<body $S{'Body'}>
$S{'Header'}
$Menu
_EOF_

	if ($S{'NoMove'}) {
		push(@Record, shift(@Record));
		@Record = reverse(@Record);
	}

	#/*--- リファレンス生成		---*/
	#
	#  @Record1 実際の記事が格納されている配列
	#  @Record2 配列番号(=記事番号)の要素は@Reocrd1へのリファレンス
	#  @Record3 ルート記事の記事番号が格納されている配列
	#
	foreach (1 .. $#Record) {
		%Field = stdio::ReadData(split /\t/, $Record[$_]);
		$Record3[$Field{'Code'}] = \$Record[$_];
		if (!$Set{$Field{'Root'}}) {
			push(@Record2, $Field{'Root'});
			$Set{$Field{'Root'}} = 1;
		}
		%Field = ();
	}
	$FileHead{'Lines'} = $#Record2 + 1;
	@Record2 = reverse(@Record2) if ($S{'NoMove'});

	#/*--- 1ページ目の場合		---*/
	if (!$STDIN{'start'} || $STDIN{'start'} <= 1) {
		$STDIN{'start'} = 1;
		if ($S{'PageMax'} >= $FileHead{'Lines'}) {
			$pageEnd   = $FileHead{'Lines'};
		} else {
			$nextStart = $STDIN{'start'} + $S{'PageMax'};
			$pageEnd   = $STDIN{'start'} + $S{'PageMax'} - 1;
			$nextLink  = qq|<a href="$Script?start=$nextStart">|;
			$nextLinkd = qq|</a>|;
		}

	#/*--- 2ページ目以降の場合	---*/
	} else {
		$backStart = $STDIN{'start'} - $S{'PageMax'};
		$backStart = 1 if ($backStart < 1);
		$backLink  = qq|<a href="$Script?start=$backStart">|;
		$backLinkd = qq|</a>|;
		if ($STDIN{'start'} + $S{'PageMax'} > $FileHead{'Lines'}) {
			$pageEnd   = $FileHead{'Lines'};
		} else {
			$nextStart = $STDIN{'start'} + $S{'PageMax'};
			$pageEnd   = $STDIN{'start'} + $S{'PageMax'} - 1;
			$nextLink  = qq|<a href="$Script?start=$nextStart">|;
			$nextLinkd = qq|</a>|;
		}
	}
	$allPages  = int($FileHead{'Lines'} / $S{'PageMax'});
	$allPages ++ if ($FileHead{'Lines'} % $S{'PageMax'} != 0);
	$nowPage   = int(($STDIN{'start'}-1)/$S{'PageMax'}) + 1;

	print qq|<hr noshade>\n|;
	print qq|新着順　<b>$STDIN{'start'}</b>件 -&gt; <b>$pageEnd</b>件 / 全投稿 <b>$FileHead{'Lines'}</b>件中 [ $backLink←前$backLinkd｜$nextLink次→$nextLinkd ]\n|;
	print qq|<hr noshade>\n|;
	print qq|<small>$S{'NewTime'}時間以内の投稿には$S{'NewMark'}が付いています。|;
	print  q|更新されたツリーが上に表示されます。| if (!$S{'NoMove'});
	print qq|</small></p>\n|;
	print qq|<div align=center>\n|;
	print qq|<table border=0 width=95%>\n|;
	print qq|  <tr>\n|;
	print qq|    <td width=100% nowrap>\n|;
	$S{'NewTime'} *= 3600;

	$x = 0;
	for ($i = $STDIN{'start'} - 1; $i <= $pageEnd - 1; $i ++) {
		%Field = stdio::ReadData(split /\t/, ${$Record3[$Record2[$i]]});
		$Field{'Title'} = substr($Field{'Title'}, 0, 40) . '...' if (length($Field{'Title'}) > 40);
		$newMark = (time - $Field{'Time'} < $S{'NewTime'}) ? $S{'NewMark'} : undef;
		$Field{'Time'} = stdio::SetTime($S{'TimeFormat'},$S{'TimeZone'},$Field{'Time'});
		print qq|      <dl>\n|;
		if ($Field{'Title'} eq '<DELETED>'){
			print qq|        <dt><a href="$Script?mode=setview&amp;code=$Field{'Code'}"><img src="dir.gif" border=0 alt="一括表\示"></a> <font color=$S{'ftcolorDeleted'}>DELETED <small><b>&lt;削除&gt;</b> $Field{'Time'} [No.$Field{'Code'}]</small></font>\n|;}

		else{
			print qq|        <dt><a href="$Script?mode=setview&amp;code=$Field{'Code'}"><img src="dir.gif" border=0 alt="一括表\示"></a> <a href="$Script?mode=view&amp;code=$Field{'Code'}">$Field{'Title'}</a> <small><b>$Field{'Name'}</b> $Field{'Time'} [No.$Field{'Code'}]</small> $newMark\n|;}

		foreach (split /:/, $Field{'Reply'}) {
			RecursiveCall_for_mainThread($_);
		}
		print qq|      </dl>\n|;
		%Field = ();
	}
	print qq|    </td>\n|;
	print qq|  </tr>\n|;
	print qq|</table>\n|;
	print qq|</div>\n|;
	print "<p align=center>";
	print " $backLink" . "Prev$backLinkd ";
	print qq| [ <a href="$Script?start=1">1</a>/ ] |;
	if ($allPages <= 10) {
		for ($i=1; $i<=$allPages; $i++) {
			if ($i == $nowPage) {
				print  qq| <b>$i</b> |;
			} else {
				printf(qq| <a href="$Script?start=%d">$i</a> |,($i-1)*$S{'PageMax'}+1);
			}
		}
	} elsif ($nowPage <= 5) {
		for ($i=1; $i<10; $i++) {
			if ($i == $nowPage) {
				print  qq| <b>$i</b> |;
			} else {
				printf(qq| <a href="$Script?start=%d">$i</a> |,($i-1)*$S{'PageMax'}+1);
			}
		}
	} elsif ($allPages - $nowPage <= 4) {
		for ($i=$allPages-8; $i<=$allPages; $i++) {
			if ($i == $nowPage) {
				print  qq| <b>$i</b> |;
			} else {
				printf(qq| <a href="$Script?start=%d">$i</a> |,($i-1)*$S{'PageMax'}+1);
			}
		}
	} else {
		for ($i=$nowPage-4; $i<=$nowPage+4; $i++) {
			if ($i == $nowPage) {
				print  qq| <b>$i</b> |;
			} else {
				printf(qq| <a href="$Script?start=%d">$i</a> |,($i-1)*$S{'PageMax'}+1);
			}
		}
	}
	printf(qq| [ /<a href="$Script?start=%d">$allPages</a> ] |,($allPages-1)*$S{'PageMax'}+1);
	print " $nextLink" . "Next$nextLinkd ";
	print "</p>\n";
	print qq|<hr noshade>\n|;
	print qq|<br>\n|;
	OutuputSearchForm();
	print $S{'Footer'};
	print qq|<h5 align=right><a href="http://www-power.net/" target=_top title="Produced by WEB POWER"><i>$Version</i></a></h5>\n|;
	print qq|</body>\n|;
	print qq|</html>\n|;
	exit(0);
}

#/*------------------- リスト型表示 -------------------------------------------------*/

sub OutputListView {

	print <<_EOF_;

<html>
<head>
<title>$S{'Title'}</title>
</head>
<body $S{'Body'}>
$S{'Header'}
$Menu
$searchResult
<hr noshade>
_EOF_

	if (!$noMatch) {

		#/*--- 1ページ目の場合		---*/
		if (!$STDIN{'start'} || $STDIN{'start'} <= 1) {
			$STDIN{'start'} = 1;
			if ($S{'PageMax'} >= $FileHead{'Lines'}) {
				$pageEnd   = $FileHead{'Lines'};
			} else {
				$nextStart = $STDIN{'start'} + $S{'PageMax'};
				$pageEnd   = $STDIN{'start'} + $S{'PageMax'} - 1;
				$nextLink  = qq|<a href="$Script?mode=listview&amp;start=$nextStart$QueryString">|;
				$nextLinkd = qq|</a>|;
			}

		#/*--- 2ページ目以降の場合	---*/
		} else {
			$backStart = $STDIN{'start'} - $S{'PageMax'};
			$backStart = 1 if ($backStart < 1);
			$backLink  = qq|<a href="$Script?mode=listview&amp;start=$backStart$QueryString">|;
			$backLinkd = qq|</a>|;
			if ($STDIN{'start'} + $S{'PageMax'} > $FileHead{'Lines'}) {
				$pageEnd   = $FileHead{'Lines'};
			} else {
				$nextStart = $STDIN{'start'} + $S{'PageMax'};
				$pageEnd   = $STDIN{'start'} + $S{'PageMax'} - 1;
				$nextLink  = qq|<a href="$Script?mode=listview&amp;start=$nextStart$QueryString">|;
				$nextLinkd = qq|</a>|;
			}
		}
		$allPages  = int($FileHead{'Lines'} / $S{'PageMax'});
		$allPages ++ if ($FileHead{'Lines'} % $S{'PageMax'} != 0);
		$nowPage   = int(($STDIN{'start'}-1)/$S{'PageMax'}) + 1;

		print qq|新着順　<b>$STDIN{'start'}</b>件 -&gt; <b>$pageEnd</b>件 / 全投稿 <b>$FileHead{'Lines'}</b>件中 [ $backLink←前$backLinkd｜$nextLink次→$nextLinkd ]\n|;
		print qq|<hr noshade>\n|;
		print qq|　<br>\n|;
		print qq|<div align=center>\n|;
		print qq|<table border=0 width=100% cellspacing=1 cellpadding=2>\n|;
		print qq|  <tr>\n|;
		print qq|    <th width=7%  bgcolor=$S{'bgcolorListMain'}><small>番号</small></th>\n|;
		print qq|    <th width=42% bgcolor=$S{'bgcolorListMain'}><small>タイトル</small></th>\n|;
		print qq|    <th width=18% bgcolor=$S{'bgcolorListMain'}><small>投稿者</small></th>\n|;
		print qq|    <th width=19% bgcolor=$S{'bgcolorListMain'}><small>投稿日</small></th>\n|;
		print qq|    <th width=7%  bgcolor=$S{'bgcolorListMain'}><small>返信元</small></th>\n|;
		print qq|    <th width=7%  bgcolor=$S{'bgcolorListMain'}><small>参照</small></th>\n|;
		print qq|  </tr>\n|;

		foreach (@Record) {
			%Field = stdio::ReadData(split /\t/);
			$Code  = $Field{'Code'};

			#/*--- メルアドが入力されている場合	---*/
			if ($Field{'Email'} && !$Field{'SecretEmail'}){
				$Field{'Name'} = qq|  <a href="mailto:$Field{'Email'}">$Field{'Name'}</a>|;}
			elsif ($Field{'Email'} && $Field{'SecretEmail'}){
				$Field{'Name'} = qq|  <a href="$Script?mail=$Field{'Code'}">$Field{'Name'}</a>|;}

			#/*--- 親記事がある場合			---*/
			if ($Field{'Parent'}) {
				$Field{'Code'}   = sprintf("%04d",$Field{'Code'});
				$Field{'Parent'} = sprintf("%04d",$Field{'Parent'});
			} else {
				$Field{'Code'}   = qq|<a href="$Script?mode=setview&amp;code=$Code">| . sprintf("%04d",$Field{'Code'}) . q|</a>|;
				$Field{'Parent'} = '-';
			}

			if ($Field{'Title'} ne '<DELETED>') {
				$Field{'Title'} = substr($Field{'Title'}, 0, 40) . '...' if (length($Field{'Title'}) > 40);
				$celclr = $celclr eq $S{'bgcolorListA'} ? $S{'bgcolorListB'} : $S{'bgcolorListA'} ;

				print qq|  <tr>\n|;
				print qq|    <td width=7% align=center bgcolor=$celclr><small>$Field{'Code'}</small></td>\n|;
				print qq|    <td width=42% bgcolor=$celclr><a href="$Script?mode=view&amp;code=$Code">$Field{'Title'}</a></td>\n|;
				print qq|    <td width=18% bgcolor=$celclr>$Field{'Name'}</td>\n|;
				print qq|    <td width=19% align=center bgcolor=$celclr><small>| . stdio::SetTime($S{'TimeFormat'},$S{'TimeZone'},$Field{'Time'}) . qq|</small></td>\n|;
				print qq|    <td width=7%  align=center bgcolor=$celclr><small>$Field{'Parent'}</small></td>\n|;
				print qq|    <td width=7%  align=center bgcolor=$celclr><small>$Field{'Count'}</small></td>\n|;
				print qq|  </tr>\n|;

			} elsif (!$Deleted) {
				$Deleted = '<small>※ 削除された記事はリストから除外しています。</small>' . "\n";
			}
			%Field = ();
		}
		print qq|</table>\n|;
		print qq|</div>\n|;
		print $Deleted;
		print "<p align=center>";
		print " $backLink" . "Prev$backLinkd ";
		print qq| [ <a href="$Script?mode=listview&amp;start=1$QueryString">1</a>/ ] |;
		if ($allPages <= 10) {
			for ($i=1; $i<=$allPages; $i++) {
				if ($i == $nowPage) {
					print  qq| <b>$i</b> |;
				} else {
					printf(qq| <a href="$Script?mode=listview&amp;start=%d$QueryString">$i</a> |,($i-1)*$S{'PageMax'}+1);
				}
			}
		} elsif ($nowPage <= 5) {
			for ($i=1; $i<10; $i++) {
				if ($i == $nowPage) {
					print  qq| <b>$i</b> |;
				} else {
					printf(qq| <a href="$Script?mode=listview&amp;start=%d$QueryString">$i</a> |,($i-1)*$S{'PageMax'}+1);
				}
			}
		} elsif ($allPages - $nowPage <= 4) {
			for ($i=$allPages-8; $i<=$allPages; $i++) {
				if ($i == $nowPage) {
					print  qq| <b>$i</b> |;
				} else {
					printf(qq| <a href="$Script?mode=listview&amp;start=%d$QueryString">$i</a> |,($i-1)*$S{'PageMax'}+1);
				}
			}
		} else {
			for ($i=$nowPage-4; $i<=$nowPage+4; $i++) {
				if ($i == $nowPage) {
					print  qq| <b>$i</b> |;
				} else {
					printf(qq| <a href="$Script?mode=listview&amp;start=%d$QueryString">$i</a> |,($i-1)*$S{'PageMax'}+1);
				}
			}
		}
		printf(qq| [ /<a href="$Script?mode=listview&amp;start=%d$QueryString">$allPages</a> ] |,($allPages-1)*$S{'PageMax'}+1);
		print " $nextLink" . "Next$nextLinkd ";
		print "</p>\n";
	} else {
		print "　<br>\n";
	}

	&OutuputSearchForm;
	print $S{'Footer'};
	print qq|<h5 align=right><a href="http://www-power.net/" target=_top title="Produced by WEB POWER"><i>$Version</i></a></h5>\n|;
	print qq|</body>\n|;
	print qq|</html>\n|;
	exit(0);
}

#/*------------- ツリー表示のための再帰呼出し -------------------------------*/

sub RecursiveCall_for_mainThread {
	$x ++;
	Error('000 重大エラー','無限ループに入った恐れがあるため強制終了します。') if ($x > 100);
	print qq|        <dl>\n|;
	%Field = stdio::ReadData(split /\t/, ${$Record3[$_[0]]});
	$Field{'Title'} = substr($Field{'Title'}, 0, 40) . '...' if (length($Field{'Title'}) > 40);

	if ((!$Field{'Parent'} && !$_[0]) || ($Field{'Code'} == $_[0])) {
		$newMark = (time - $Field{'Time'} < $S{'NewTime'}) ? $S{'NewMark'} : undef;
		$Field{'Time'} = stdio::SetTime($S{'TimeFormat'},$S{'TimeZone'},$Field{'Time'});

		#/*--- 記事が削除されている	---*/
		if ($Field{'Title'} eq '<DELETED>'){
			print qq|        <dt>┣<font color=$S{'ftcolorDeleted'}>DELETED <small><b>&lt;削除&gt;</b> $Field{'Time'} [No.$Field{'Code'}]</small></font>\n|;

		#/*--- 記事が存在する場合	---*/
		} else {
			if ($Code == $Field{'Code'}){
				print qq|        <dt><table border=0 cellpadding=0 cellspacing=0 bgcolor=FFEEDD><tr><td>┣<font color=FF0000>$Field{'Title'} <small><b>$Field{'Name'}</b> $Field{'Time'} [No.$Field{'Code'}] $here</small></font></td></tr></table>\n|;}
			else{
				print qq|        <dt>┣<a href="$Script?mode=view&amp;code=$Field{'Code'}">$Field{'Title'}</a> <small><b>$Field{'Name'}</b> $Field{'Time'} [No.$Field{'Code'}]</small> $newMark\n|;}
		}
		if ($Field{'Reply'}) {
			foreach (split(":", $Field{'Reply'})) {
				RecursiveCall_for_mainThread($_);
			}
		}
	}
	print qq|        </dl>\n|;
}

#/*------------- 投稿内容表示 -----------------------------------------------*/

sub SeeMessages {
	@Record = stdio::ReadFile($DataFile, undef, undef, $E{'UseLock'});
	Error('110 排他制御中','只今混雑しています。時間をおいて再試行してください。') if ($Record[0] == -2);

	foreach (@Record) {
		%Field = stdio::ReadData(split /\t/, $Record[$i]);
		$Record3[$Field{'Code'}] = \$_;
		$i ++;
	}

	for ($i = 1; $i <= $#Record; $i ++) {
		%Field = stdio::ReadData(split /\t/, $Record[$i]);
		if ($Field{'Code'} == $STDIN{'code'}) {
			Error('120 レコード未検出','指定されたコードの記事は削除されています。') if ($Field{'Title'} eq '<DELETED>');
			$find = 1;
			last;
		}
		%Field = ();
	}
	Error('120 レコード未検出','指定されたコードの記事は存在しません。') if (!$find);

	#/*--- 参照数カウント		---*/
	$Field{'Count'} ++;
	$Record[$i] =
		  'Code='	. $Field{'Code'}	. "\t"
		. 'Time='	. $Field{'Time'}	. "\t"
		. 'Name='	. $Field{'Name'}	. "\t"
		. 'Email='	. $Field{'Email'}	. "\t"
		. 'SecretEmail='. $Field{'SecretEmail'} . "\t"
		. 'Url='	. $Field{'Url'}		. "\t"
		. 'Age='	. $Field{'Age'}		. "\t"
		. 'Sex='	. $Field{'Sex'}		. "\t"
		. 'Title='	. $Field{'Title'}	. "\t"
		. 'Count='	. $Field{'Count'}	. "\t"
		. 'Comment='	. $Field{'Comment'}	. "\t"
		. 'MsgType='	. $Field{'MsgType'}	. "\t"
		. 'AutoLink='	. $Field{'AutoLink'}	. "\t"
		. 'Passwd='	. $Field{'Passwd'}	. "\t"
		. 'Count='	. $Field{'Count'}	. "\t"
		. 'Parent='	. $Field{'Parent'}	. "\t"
		. 'Reply='	. $Field{'Reply'}	. "\t"
		. 'Root='	. $Field{'Root'}	. "\t"
		. 'Sendmail='	. $Field{'Sendmail'}	. "\t"
		. 'Host='	. $Field{'Host'}	. "\t"
		. 'Addr='	. $Field{'Addr'}	. "\t"
		. 'Agent='	. $Field{'Agent'}	. "\t"
		. "\n";

	stdio::FileLock($DataFile,$E{'UseLock'},@Record) if (stdio::LockCheck($DataFile,$E{'UseLock'}));

	#/*--- メルアドが入力されている場合	---*/
	if ($Field{'Email'} && !$Field{'SecretEmail'}){
		$Field{'Name'} = qq|  <a href="mailto:$Field{'Email'}">$Field{'Name'}</a>|;}

	elsif ($Field{'Email'} && $Field{'SecretEmail'}){
		$Field{'Name'} = qq|  <a href="$Script?mail=$STDIN{'code'}">$Field{'Name'}</a>|;}

	#/*--- URLが入力されている場合		---*/
	if ($Field{'Url'} =~ /http:\/\/.+/) {
		$Field{'Url'} = "\n"
			      . qq|  <hr noshade>\n|
			      . qq|  <a href="$Field{'Url'}" target=_top>$Field{'Url'}</a>\n|;
	} else {
		undef $Field{'Url'};
	}

	#/*--- 性別と年齢の設定			---*/
	if ($Field{'Age'}){
		$Field{'Age'} .= '歳';}

	if ($Field{'Sex'} eq 'male'){
		$Field{'Sex'} = '男性';}
	elsif ($Field{'Sex'} eq 'female'){
		$Field{'Sex'} = '女性';}

	if ($Field{'Sex'} && $Field{'Age'}){
		$Field{'Name'} .= " <small>($Field{'Age'}/$Field{'Sex'})</small>";}
	elsif ($Field{'Sex'} || $Field{'Age'}){
		$Field{'Name'} .= " <small>($Field{'Age'}$Field{'Sex'})</small>";}

	$Field{'Comment'} = stdio::InlineLink($Field{'Comment'}) if ($Field{'AutoLink'});
	$Field{'Comment'} =~ s/\{(\d)\}/<a href="$Script?mode=view&amp;code=$1">&lt;$1&gt;<\/a>/g;
	$Field{'Time'}    = stdio::SetTime($S{'TimeFormat'},$S{'TimeZone'},$Field{'Time'});

	#/*--- 図表モードの場合			---*/
	if ($Field{'MsgType'} eq 'pre') {
		foreach (split(/<br>/, $Field{'Comment'})) {
			if (/^&gt;/ || /^＞/) {
				$Comment .= "<cite>$_</cite>\n";
			} else {
				$Comment .= "$_\n";
			}
		}
		$Comment = '<big>' . $Comment . '</big>' if ($ENV{'HTTP_USER_AGENT'} =~ /MSIE/);
		$Comment = '<pre>' . $Comment . '</pre>';

	#/*--- 改行無効モードの場合		---*/
	} elsif ($Field{'MsgType'} eq 'nobr') {
		foreach (split(/<br>/, $Field{'Comment'})) {
			if (/^&gt;/ || /^＞/) {
				$Comment .= "<cite>$_</cite><br>\n";
			} else {
				$Comment .= $_;
			}
		}

	#/*--- 改行有効モードの場合		---*/
	} else {
		foreach (split(/<br>/, $Field{'Comment'})) {
			if (/^&gt;/ || /^＞/) {
				$Comment .= "<cite>$_</cite><br>\n";
			} else {
				$Comment .= "$_<br>\n";
			}
		}
	}
	$Field{'Comment'} = $Comment;
	undef $Comment;

	#/*--- 投稿内容表示開始			---*/
	print "Content-type: text/html\n\n";
	print <<_EOF_;

<html>
<head>
<title>$S{'Title'} [$Field{'Title'}]</title>
</head>
<body $S{'Body'}>
$S{'Header'}
$Menu

  <hr noshade>
  <table border=0 bgcolor=$S{'bgcolorTitleBar'} width=100% cellspacing=0 cellpadding=3>
    <tr>
      <td><a name="title"><font color=$S{'ftcolorTitleBar'} size=5>$Field{'Title'}</font></a></td>
    </tr>
  </table>
  <small>No.$Field{'Code'} - $Field{'Count'}hit(s)</small>
  <p>$Field{'Comment'}</p>$Field{'Url'}
  <hr size=1>
  <table border=0>
    <tr>
      <td align=right>投稿者　：</td>
      <td>$Field{'Name'}</td>
    </tr>
    <tr>
      <td align=right>投稿日　：</td>
      <td>$Field{'Time'}</td>
    </tr>
    <tr>
      <td align=right>エージェント　：</td>
      <td>$Field{'Agent'}</td>
    </tr>
  </table>
  <table width=100% border=0 cellspacing=0 cellpadding=0>
    <tr>
      <td width=100%><hr size=1>
      <td align=right nowrap><table border=1 cellspacing=0 cellpadding=3>
        <tr><form method=$method action="$Script"><input type=hidden name="res" value="$STDIN{'code'}">
          <td nowrap><small><input type=checkbox name=quote>引用</small>　<input type=submit value="　返信　"></td>
        </form><form method=$method action="$Script"><input type=hidden name=mode value=delete><input type=hidden name=Code value=$STDIN{'code'}>
          <td nowrap><small>パスワード</small>　<input type=password name=Passwd size=8 maxlength=16><input type=submit value="削除"></td>
        </form></tr>
      </table></td>
    </tr>
  </table>
  <h2><a href="$Script?mode=setview&amp;code=$Field{'Root'}">関連記事一覧</a></h2>

<table border=0 align=center width=95%>
  <tr>
    <td>
      <dl>
_EOF_

	$Code = $Field{'Code'};
	$Root = $Field{'Root'};
	$S{'NewTime'} *= 3600;

	#/*--- ツリー表示構成開始				---*/
	for ($i = 1; $i <= $#Record; $i ++) {
		$x = 0;
		%Field = stdio::ReadData(split /\t/, $Record[$i]);
		if ($Root == $Field{'Code'}) {
			$Field{'Time'} = stdio::SetTime($S{'TimeFormat'},$S{'TimeZone'},$Field{'Time'});

			#/*--- 記事が削除されている場合		---*/
			if ($Field{'Title'} eq '<DELETED>') {
				print qq|        <dt><font color=$S{'ftcolorDeleted'}>DELETED <small><b>&lt;削除&gt;</b> $Field{'Time'} [No.$Field{'Code'}]</small></font>\n|;
				foreach (split(":", $Field{'Reply'})) {
					RecursiveCall_for_mainThread($_);
				}

			#/*--- 記事が存在する場合		---*/
			} else {
				$Field{'Title'} = substr($Field{'Title'}, 0, 40) . '...' if (length($Field{'Title'}) > 40);
				if ($Code == $Field{'Code'}) {
					print qq|        <dt><table border=0 cellpadding=0 cellspacing=0 bgcolor=FFEEDD><tr><td><font color=FF0000>$Field{'Title'} <small><b>$Field{'Name'}</b> $Field{'Time'} [No.$Field{'Code'}] $here</small></font></td></tr></table>\n|;
					if ($Field{'Reply'}) {
						foreach (split(":", $Field{'Reply'})) {
							RecursiveCall_for_mainThread($_);
						}
					} else {
						last;
					}
				} else {
					$newMark = (time - $Field{'Time'} < $S{'NewTime'}) ? $S{'NewMark'} : undef;
					print qq|        <dt><a href="$Script?mode=view&amp;code=$Field{'Code'}">$Field{'Title'}</a> <small><b>$Field{'Name'}</b> $Field{'Time'} [No.$Field{'Code'}]</small> $newMark\n|;
					foreach (split(":", $Field{'Reply'})) {
						RecursiveCall_for_mainThread($_);
					}
				}
			}
		}
	}
	print <<_EOF_;
      </dl>
    </td>
  </td>
</table>
<hr noshade>
$S{'Footer3'}
</body>
</html>

_EOF_

	exit(0);
}

#/*------------- 一括表示 ---------------------------------------------------*/

sub OutputSetView {
	Error('100 ファイル未検出','データファイルが存在しません。') if (!-e $DataFile);
	open(FILE, $DataFile) || Error('ファイル入出力エラー','データファイルのオープンができません。');
	while (<FILE>) {
		%Field = stdio::ReadData(split /\t/);
		if ($Field{'Root'} == $STDIN{'code'}) {
			$find = 1 if ($Field{'Code'} == $STDIN{'code'});
			$Record[$i] = $_;
			$Record3[$Field{'Code'}] = \$Record[$i];
			$i ++;
		}
		%Field = ();
	}
	close(FILE);
	Error('120 レコード未検出','指定されたコードの記事は存在しません。') if (!$find);

	print "Content-type: text/html\n\n";
	print <<_EOF_;

<html>
<head>
<Title>$S{'Title'} [一括表\示]</Title>
</head>
<body $S{'Body'}>
$S{'Header'}
$Menu
<hr noshade>
<dl>

_EOF_

	$x = 0;
	%Field = stdio::ReadData(split "\t", ${$Record3[$STDIN{'code'}]});

	#/*--- 記事が削除されている	---*/
	if ($Field{'Title'} eq '<DELETED>') {
		print qq|<dt>\n|;
		print qq|  <p><font color=$S{'ftcolorDeleted'}><font size=5>DELETED</font> <small> $Field{'date'} [No.$Field{'Code'}]</small></font>\n|;
		print qq|  <blockquote>\n|;
		print qq|    <p><font color=$S{'ftcolorDeleted'}>この記事は削除されています。</font></p>\n|;
		print qq|  </blockquote>\n|;

	#/*--- 記事が存在する場合			---*/
	} else {

		#/*--- メルアドが入力されている場合	---*/
		if ($Field{'Email'} && !$Field{'SecretEmail'}){
			$Field{'Name'} = qq|  <a href="mailto:$Field{'Email'}">$Field{'Name'}</a>|;}

		elsif ($Field{'Email'} && $Field{'SecretEmail'}){
			$Field{'Name'} = qq|  <a href="$Script?mail=$STDIN{'code'}</a>|;}


		if ($Field{'Age'}){
			$Field{'Age'} .= '歳';}

		if ($Field{'Sex'} eq 'male'){
			$Field{'Sex'} = '男性';}
		elsif ($Field{'Sex'} eq 'female'){
			$Field{'Sex'} = '女性';}

		if ($Field{'Sex'} && $Field{'Age'}){
			$Field{'Name'} .= " ($Field{'Age'}/$Field{'Sex'})";}
		elsif ($Field{'Sex'} || $Field{'Age'}){
			$Field{'Name'} .= " ($Field{'Age'}$Field{'Sex'})";}

		$Field{'Comment'} = stdio::InlineLink($Field{'Comment'}) if ($Field{'AutoLink'});
		$Field{'Comment'} =~ s/\{(\d)\}/<a href="$Script\?mode=view&amp;code=$1">&lt;$1&gt;<\/a>/g;
		$Field{'Time'}    = stdio::SetTime($S{'TimeFormat'},$S{'TimeZone'},$Field{'Time'});

		#/*--- 図表モードの場合			---*/
		if ($Field{'MsgType'} eq 'pre') {
			foreach (split(/<br>/, $Field{'Comment'})) {
				if (/^&gt;/ || /^＞/) {
					$Comment .= "<cite>$_</cite>\n";
				} else {
					$Comment .= "$_\n";
				}
			}
			$Comment = '<pre>' . $Comment . '</pre>';
			$Comment = '<big>' . $Comment . '</big>' if ($ENV{'HTTP_USER_AGENT'} =~ /MSIE/);

		#/*--- 改行無効モードの場合		---*/
		} elsif ($Field{'MsgType'} eq 'nobr') {
			foreach (split(/<br>/, $Field{'Comment'})) {
				if (/^&gt;/ || /^＞/) {
					$Comment .= "<cite>$_</cite><br>\n";
				} else {
					$Comment .= $_;
				}
			}

		#/*--- 改行有効モードの場合		---*/
		} else {
			foreach (split(/<br>/, $Field{'Comment'})) {
				if (/^&gt;/ || /^＞/) {
					$Comment .= "<cite>$_</cite><br>\n";
				} else {
					$Comment .= "$_<br>\n";
				}
			}
		}
		$Field{'Comment'} = $Comment;
		undef $Comment;

		#/*--- URLが入力されている場合		---*/
		if ($Field{'Url'} =~ /http:\/\/.+\..+/){
			$Field{'Comment'} .= qq|<p><a href="$Field{'Url'}" target=_top>$Field{'Url'}</a></p>\n|;}

		print qq|<dt>\n|;
		print qq|  <p><a href="$Script?mode=view&amp;code=$Field{'Code'}"><font size=5>$Field{'Title'}</font></a><br>\n|;
		print qq|  <small>　 $Field{'Name'} $Field{'Time'} [No.$Field{'Code'}] <a href="$Script?res=$Field{'Code'}">返信</a>（<a href="$Script?res=$Field{'Code'}&amp;quote=1">引用して返信</a>）</small></p>\n|;
		print qq|  <blockquote>\n|;
		print qq|    <table border=0>\n|;
		print qq|      <tr>\n|;
		print qq|        <td nowrap>$Field{'Comment'}</td>\n|;
		print qq|      </tr>\n|;
		print qq|    </table>\n|;
		print qq|  </blockquote>\n|;
	}
	foreach (split /:/, $Field{'Reply'}) {
		RecursiveCall_for_subThread($_);
	}
	print <<_EOF_;

</dl>
<form method=$method action="$Script"><input type=hidden name=mode value="deleteTree"><input type=hidden name="Code" value="$STDIN{'code'}">
  <table width=100% border=0 cellspacing=0 cellpadding=0>
    <tr>
      <td width=100%><hr size=1>
      <td align=right nowrap><table border=1 cellspacing=0 cellpadding=3>
        <tr>
          <td nowrap> パスワード　<input type=password name="Passwd" size=10 maxlength=10><input type=submit value="削除" onClick="return confirm('トピックを削除しようとしています。このトピックに投稿されている全ての記事が削除されます。\\n本当に削除してもよろしいですか?');"></td>
        </tr>
      </table>
    </tr>
  </table>
</form>
$S{'Footer3'}
</body>
</html>

_EOF_
	exit(0);
}

#/*------------- 一括表示のための再帰呼び出し -------------------------------*/

sub RecursiveCall_for_subThread {
	$x ++;
	Error('000 重大エラー','無限ループに入った恐れがあるため強制終了します。') if ($x > 100);
	print qq|<dl>\n|;

	%Field = stdio::ReadData(split "\t", ${$Record3[$_[0]]});
	if ((!$Field{'Parent'} && !$_[0]) || ($Field{'Code'} == $_[0])) {
		$Field{'Time'} = stdio::SetTime($S{'TimeFormat'},$S{'TimeZone'},$Field{'Time'});

		#/*--- 記事が削除されている	---*/
		if ($Field{'Title'} eq '<DELETED>') {
			print qq|<dt>\n|;
			print qq|  <p><font color=$S{'ftcolorDeleted'}><font size=4><b>DELETED</b></font> <small> $Field{'Time'} [No.$Field{'Code'}]</small></font>\n|;
			print qq|  <blockquote>\n|;
			print qq|    <p><font color=$S{'ftcolorDeleted'}>この記事は削除されています。</font></p>\n|;
			print qq|  </blockquote>\n|;

		#/*--- 記事が存在する場合	---*/
		} else {

			#/*--- メルアドが入力されている場合	---*/
			if ($Field{'Email'} && !$Field{'SecretEmail'}){
				$Field{'Name'} = qq|  <a href="mailto:$Field{'Email'}">$Field{'Name'}</a>|;}
			elsif ($Field{'Email'} && $Field{'SecretEmail'}){
				$Field{'Name'} = qq|  <a href="$Script?mail=$STDIN{'view'}">$Field{'Name'}</a>|;}

			if ($Field{'Age'}){
				$Field{'Age'} .= '歳';}

			if ($Field{'Sex'} eq 'male'){
				$Field{'Sex'} = '男性';}
			elsif ($Field{'Sex'} eq 'female'){
				$Field{'Sex'} = '女性';}

			if ($Field{'Sex'} && $Field{'Age'}){
				$Field{'Name'} .= " ($Field{'Age'}/$Field{'Sex'})";}
			elsif ($Field{'Sex'} || $Field{'Age'}){
				$Field{'Name'} .= " ($Field{'Age'}$Field{'Sex'})";}

			$Field{'Comment'} = stdio::InlineLink($Field{'Comment'}) if ($Field{'AutoLink'});
			$Field{'Comment'} =~ s/\{(\d)\}/<a href="$Script\?mode=view&amp;code=$1">&lt;$1&gt;<\/a>/g;

			#/*--- 図表モードの場合			---*/
			if ($Field{'MsgType'} eq 'pre') {
				foreach (split(/<br>/, $Field{'Comment'})) {
					if (/^&gt;/) {
						$Comment .= "<cite>$_</cite>\n";
					} else {
						$Comment .= "$_\n";
					}
				}
				$Comment = '<pre>' . $Comment . '</pre>';
				$Comment = '<big>' . $Comment . '</big>' if ($ENV{'HTTP_USER_AGENT'} =~ /MSIE/);

			#/*--- 改行無効モードの場合		---*/
			} elsif ($Field{'MsgType'} eq 'nobr') {
				foreach (split(/<br>/, $Field{'Comment'})) {
					if (/^&gt;/) {
						$Comment .= "<cite>$_</cite><br>\n";
					} else {
						$Comment .= $_;
					}
				}

			#/*--- 改行有効モードの場合		---*/
			} else {
				foreach (split(/<br>/, $Field{'Comment'})) {
					if (/^&gt;/) {
						$Comment .= "<cite>$_</cite><br>\n";
					} else {
						$Comment .= "$_<br>\n";
					}
				}
			}
			$Field{'Comment'} = $Comment;
			undef $Comment;

			#/*--- URLが入力されている場合		---*/
			if ($Field{'Url'} =~ /http:\/\/.+\..+/) {
				$Field{'Comment'} .= qq|<p><a href="$Field{'Url'}" target=_top>$Field{'Url'}</a></p>\n|;
			}

			print qq|<dt>\n|;
			print qq|  <p><a href="$Script?mode=view&amp;code=$Field{'Code'}"><font size=4><b>$Field{'Title'}</b></font></a><br>\n|;
			print qq|  <small>　 $Field{'Name'} $Field{'Time'} [No.$Field{'Code'}] <a href="$Script?res=$Field{'Code'}">返信</a>（<a href="$Script?res=$Field{'Code'}&amp;quote=1">引用して返信</a>）</small></p>\n|;
			print qq|  <blockquote>\n|;
			print qq|    <table border=0>\n|;
			print qq|      <tr>\n|;
			print qq|        <td nowrap>$Field{'Comment'}</td>\n|;
			print qq|      </tr>\n|;
			print qq|    </table>\n|;
			print qq|  </blockquote>\n|;
		}
		if ($Field{'Reply'}) {
			foreach (split(/:/, $Field{'Reply'})) {
				RecursiveCall_for_subThread($_);
			}
		}
	}
	%Field = ();
	print qq|</dl>\n|;
}

#/*------------- メール送信フォーム出力 -------------------------------------*/

sub OutputSendMailForm {

	#/*--- データファイルのオープン		---*/
	Error('100 ファイル未検出','データファイルが存在しません。') if (!-e $DataFile);
	open(FILE, $DataFile) || Error('101 ファイル読込エラー','データファイルの読み込みができません。');
	while (<FILE>) {
		%Field = stdio::ReadData(split "\t");
		if ($Field{'Code'} == $STDIN{'mail'}) {
			if ($Field{'Title'} eq '<DELETED>'){
				Error('120 レコード未検出','指定されたコードの記事は削除されています。');}
			elsif (!$Field{'SecretEmail'}){
				Error('120 レコード未検出','指定されたコードの記事の投稿者にはメール送信できません。');}

			$find = 1;
			last;
		}
		%Field = ();
	}
	close(FILE);
	Error('120 レコード未検出','指定されたコードの記事は存在しません。') if (!$find);

	#/*--- メール送信用HTML表示開始		---*/
	print 'Content-type: text/html' . $fcode . "\n\n";
	print <<_EOF_;

<html>
<head>
<title>$S{'Title'} [$Field{'Name'}さんへメール送信]</title>
</head>
<body $S{'Body'} onLoad="document.mailForm.Name.focus();">
$S{'Header'}
$Menu

<font size=5>$Field{'Name'}さんへメール送信</font>
<hr noshade size=3>
_EOF_

	OutputSendmailForm();
	exit(0);
}

#/*------------- 匿メール送信フォーム出力 -----------------------------------*/

sub OutputSendmailForm {
	local(%Value) = @_;
	$CcChecked = ' checked' if ($STDIN{'Cc'});

	print <<_EOF_;

<form method=$method action="$Script" name="mailForm"><input type=hidden name="mode" value="sendmail"><input type=hidden name="code" value="$STDIN{'mail'}">
  <table border=0 cellspacing=0>
    <tr>
      <td align=right>名前　</td>
      <td><input name=Name size=30 value="$Value{'Name'}" maxlength=50></td>
    </tr>
    <tr>
      <td align=right>メール　</td>
      <td><input name=Email size=30 value="$Value{'Email'}" maxlength=50><small>　<input type=checkbox name="Cc"$CcChecked>自分宛にも送信</small></td>
    </tr>
    <tr>
      <td align=right>　タイトル　</td>
      <td><input name=Title size=40 value="$Value{'Title'}" maxlength=60></td>
    </tr>
    <tr>
      <td align=right>本文　</td>
      <td><textarea name=Comment rows=10 cols=60 wrap=hard>$Value{'Comment'}</textarea></td>
    </tr>
    <tr>
      <td></td>
      <td>　<br><input type=submit value="　　送信する　　"><input type=reset value="リセット" onClick="return confirm('フォーム入力内容をリセットします。よろしいですか?');"></td>
    </tr>
  </table>
</form>
<hr noshade>
<font size=2>
<ul>
  <li>半角カタカナ、機種依存文字（全角ローマ数字、○の中の数字等）、タグは使えません。
  <li>送信者のリモートホスト、ブラウザの情報も送信されます。
</ul>
</font>
</body>
</html>

_EOF_
	exit(0);
}

#/*------------- 匿メール送信 -----------------------------------------------*/

sub SecretSendMail {

	#/*--- エラーのチェック		---*/
	if ($S{'ScriptUrl'} && $ENV{'HTTP_REFERER'} !~ /$S{'ScriptUrl'}/i){
		Error('204 参照元エラー','外部からの投稿はできません。');}

	elsif ($method eq 'POST' && $ENV{'REQUEST_METHOD'} ne 'POST'){
		Error('203 メソッドエラー','不正利用の可能性があります。');}

	#/*--- フォーム入力内容のチェック	---*/
	if ($STDIN{'Name'} eq "") {
		$ErrorMessage = qq|<li><b>名前</b>を入力して下さい。\n|;
	} else {
		if (length($STDIN{'Name'}) > 50) {
			$ErrorMessage .= qq|<li><b>名前</b>は50バイト以内で入力して下さい。（現在 | . length($STDIN{'Name'}) . qq|バイト）\n|;
		}
	}
	if ($STDIN{'Email'} ne "") {
		if ($STDIN{'Email'} !~ /^([\w\+-]+@[\w\+-]+\.[\w\+\.-]+)$/) {
			$ErrorMessage .= qq|<li><b>メールアドレス</b>の形式が間違っています。（半角で正しく入力してください）\n|;
		} elsif (length($STDIN{'Email'}) > 50) {
			$ErrorMessage .= qq|<li><b>メールアドレス</b>は50バイト以内で入力して下さい。（現在 | . length($STDIN{'Name'}) . qq|バイト）\n|;
		}
		$EmailCc = $STDIN{'Email'} if ($STDIN{'Cc'});
	} elsif ($STDIN{'Cc'}) {
		$ErrorMessage .= qq|<li>あなた宛にも送信する場合、<b>メールアドレス</b>を入力してください。\n|;
	}
	
	if ($STDIN{'Title'} eq "") {
		$ErrorMessage .= qq|<li><b>タイトル</b>を入力して下さい。\n|;
	} else {
		if (length($STDIN{'Name'}) > 60){
			$ErrorMessage .= qq|<li><b>タイトル</b>は60バイト以内で入力して下さい。（現在 | . length($STDIN{'Name'}) . qq|バイト）\n|;}
	}
	if ($STDIN{'Comment'} eq "") {
		$ErrorMessage .= qq|<li><b>コメント</b>を入力して下さい。\n|;
	} else {
		if (length($STDIN{'Comment'}) > 4096){
			$ErrorMessage .= qq|<li><b>コメント</b>は4096バイト以内で入力して下さい。（現在 | . length($STDIN{'Comment'}) . qq|バイト）\n|;}
	}

	#/*--- フォーム入力内容不備 		---*/
	if ($ErrorMessage) {
		print "Content-type: text/html\n\n";
		print qq|<html>\n|;
		print qq|<head>\n|;
		print qq|<title>$S{'Title'} [フォーム入力ミス]</title>\n|;
		print qq|</head>\n|;
		print qq|<body $S{'Body'}>\n|;
		print qq|<img src="$Script?error" width=28 height=28 alt="&lt;!&gt;"><font size=5><b> フォーム入力ミス</b></font>\n|;
		print qq|<hr size=1 width=65% align=left>\n|;
		print qq|<p>　フォームの入力内容に入力漏れ、指定文字数超過等の不備があったため、投稿処理は一旦中断されました。検出された該当箇所をもう一度ご確認の上、再試行してみてください。繰り返し、エラーメッセージが表\示される場合は、このサイトの管理者に連絡してください。</p>\n|;
		print qq|<ul>\n|;
		print qq|$ErrorMessage|;
		print qq|</ul>\n|;
		print qq|<hr noshade>\n|;
		OutputSendmailForm(%STDIN);
		exit(0);
	}

	if ($STDIN{'Email'} eq ""){
		$STDIN{'Email'} = 'anonymous@on.the.net';}

	#/*--- データファイルのオープン		---*/
	Error('100 ファイル未検出','データファイルが存在しません。') if (!-e $DataFile);
	open(FILE, $DataFile) || Error('ファイル入出力エラー','データファイルのオープンができません。');
	while (<FILE>) {
		%Field = stdio::ReadData(split "\t");
		if ($Field{'Code'} == $STDIN{'code'}) {
			if ($Field{'Title'} eq '<DELETED>'){
				Error('120 レコード未検出','指定されたコードの記事は削除されています。');}
			elsif (!$Field{'SecretEmail'}){
				Error('407 メール送信不可','指定されたコードの記事の投稿者にはメール送信できません。');}

			$find = 1;
			last;
		}
		%Field = ();
	}
	close(FILE);
	Error('120 レコード未検出','指定されたコードの記事は存在しません。') if (!$find);

	$STDIN{'Comment'} =~ s/<br>/\n/g;
	$STDIN{'Comment'} =~ s/&lt;/</g;
	$STDIN{'Comment'} =~ s/&gt;/>/g;
	$STDIN{'Comment'} =~ s/&amp;/&/g;
	$STDIN{'Comment'} =~ s/&quot;/"/g;
	$STDIN{'Comment'} =~ s/[\n|\s]*$//g;
	$Message =<<_EOF_;

このメールは$S{'Title'}からフォーム経由で送信しています。

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

[投 稿 日] $TimeNow
[ホ ス ト] $REMOTE_HOST
[アドレス] $REMOTE_ADDR
[ブラウザ] $HTTP_USER_AGENT

$STDIN{'Comment'}

---------------------------------------------------------------------
_EOF_

	if (open(FILE, $FlagFile)) {
		@File = split "\t", <FILE>;
		close(FILE);
	}
	Error('408 送信済み','送信は完了しています。重複送信はできません。') if ($File[0] eq $Field{'Email'} && $File[1] eq $ENV{'REMOTE_ADDR'} && $File[2] == length($STDIN{'Comment'}));

	#/*--- 実際にメール送信する	---*/
	Error('608 メール送信エラー','メールの送信に失敗しました。') if (!stdio::SendMail($sendmail,$Field{'Email'},$EmailCc,undef,"$STDIN{'Name'} <$STDIN{'Email'}>",undef,$STDIN{'Title'},$Message));

	#/*--- 重複送信防止のためのフラッグ
	if (open(FILE, ">$FlagFile")) {
		print FILE "$Field{'Email'}\t$ENV{'REMOTE_ADDR'}\t" . length($STDIN{'Comment'});
		close(FILE);
	}

	Error('送信完了','メールを送信しました。',$Field{'Name'} . 'さんへのメール送信は完了しました。');
	exit(0);
}

#/*------------- 投稿ページ表示 ---------------------------------------------*/

sub OutputSubmitForm {
	if ($E{'RunMode'} == 1){
		Error('403 投稿不可','閲覧モードになっているため投稿できません。');}

	#/*--- 返信の場合		---*/
	if ($STDIN{'res'}) {
		Error('100 ファイル未検出','データファイルが存在しません。') if (!-e $DataFile);
		open(FILE, $DataFile) || Error('100 ファイル未検出','データファイルが存在しません。');
		while (<FILE>) {
			%Field = stdio::ReadData(split /\t/);
			if ($STDIN{'res'} == $Field{'Code'}) {
				$subject = '[' . $Field{'Title'} . ']への返信';
				if ($Field{'Title'} eq '<DELETED>'){
					Error('120 レコード未検出','返信しようとしている記事は削除されています。');
				} elsif ($Field{'Title'} =~ /^Re\((\d+)\):/ ) {
					$ResCode = $1 + 1;
					$Field{'Title'} =~ s/Re\(\d+\):(.*)/Re($ResCode):$1/g;

				} else {
					$Field{'Title'} = "Re(1):$Field{'Title'}";
				}
				$find = 1;
				last;
			}
			%Field = ();
		}
		close(FILE);
		Error('120 レコード未検出','返信しようとしている記事は存在しません。') if (!$find);

		#/*--- 引用符の挿入	---*/
		if ($STDIN{'quote'}) {
			$Field{'Comment'} = "&gt; $Field{'Comment'}";
			$Field{'Comment'} =~ s/<br>/\n&gt; /ig;
		} else {
			undef $Field{'Comment'};
		}

	#/*--- 新規投稿の場合		---*/
	} else {
		$subject = '新規投稿'
	}

	if (!$noCookie) {
		%Cookie = stdio::GetCookie($S{'CookieName'});
		$Cookie{'Comment'}= $Field{'Comment'};
		$Cookie{'Title'}  = $Field{'Title'};
	}
	$Cookie{'Parent'} = $Field{'Code'};
	$Cookie{'Root'}   = $Field{'Root'};

	print "Content-type: text/html\n\n" if (!$noCookie);
	print <<_EOF_;

<html>
<head>
<Title>$S{'Title'} [$subject]</Title>
</head>
<body $S{'Body'}>
$S{'Header'}
$Menu
<font size=5>$subject</font>
<hr noshade>

_EOF_

	OutputWriteForm(%Cookie);
	print "</body>\n";
	print "</html>\n";
	exit(0);
}

#/*------------- 書き込み用フォーム出力 -------------------------------------*/

sub OutputWriteForm {
	local(%Value) = @_;
	$Value{'Url'}       = 'http://'  if ($Value{'Url'} eq "");
	$Value{'AutoLink'}  = ' checked' if ($Value{'AutoLink'} || !$Value{'mode'});
	$Value{'SetCookie'} = ' checked' if ($Value{'SetCookie'} || !$Value{'mode'});
	if ($Value{'MsgType'} eq 'nobr') {
		$Value{'MstType.nobr'}  = ' checked';
	} elsif ($Value{'MsgType'} eq 'pre') {
		$Value{'MstType.pre'}   = ' checked';
	} else {
		$Value{'MstType.normal'}= ' checked';
	}
	if ($S{'SetWhoForm'}) {
		if ($Value{'Sex'} eq 'male'){
			$Value{'sexChecked1'} = ' checked';}

		elsif ($Value{'Sex'} eq 'female'){
			$Value{'sexChecked2'} = ' checked';}

		$whoform = qq|　<small><input type=radio value="female" name="Sex"$Value{'sexChecked2'}>女性 <input type=radio name="Sex" value="male"$Value{'sexChecked1'}>男性　<input name=Age size=2 value="$Value{'Age'}" maxlength=2 style="ime-mode:disabled">歳</small>|;
	}
	if ($sendmail) {
		$Value{'Sendmail'}   = ' checked' if ($Value{'Sendmail'});
		$Value{'SecretEmail'}= ' checked' if ($Value{'SecretEmail'});
		$Emailok = "　<small><input type=checkbox name=Sendmail$Value{'Sendmail'}>返信をメールで受信　<input type=checkbox name=SecretEmail$Value{'SecretEmail'}>アドレス非開示</small>";
	}

	$Value{'Comment'}   =~ s/<br>/\n/g;

	print <<_EOF_;

<form method=$method action="$Script"><input type=hidden name=mode value=input><input
 type=hidden name=Parent value=$Value{'Parent'}><input type=hidden name=Root value=$Value{'Root'}>
  <table border=0 cellpadding=0>
    <tr>
      <td align=right>名前　</td>
      <td><input name="Name" size=35 maxlength=40 value="$Value{'Name'}">$whoform</td>
    </tr>
    <tr>
      <td align=right>メール　</td>
      <td><input name="Email" size=35 maxlength=50 value="$Value{'Email'}" style="ime-mode:disabled">$Emailok</td>
    </tr>
    <tr>
      <td align=right>URL　</td>
      <td><input name="Url" size=48 value="$Value{'Url'}" maxlength=100 style="ime-mode:disabled"></td>
    </tr>
    <tr>
      <td align=right>タイトル　</td>
      <td><input name="Title" size=48 value="$Value{'Title'}" maxlength=60></td>
    </tr>
    <tr>
      <td align=right>コメント　</td>
      <td><textarea name="Comment" rows=15 cols=67 wrap=off>$Value{'Comment'}</textarea><br>
      <small><input type=radio name=MsgType value=normal$Value{'MstType.normal'}>改行有効　<input type=radio name=MsgType value=nobr$Value{'MstType.nobr'}>改行無効　<input type=radio name=MsgType value=pre$Value{'MstType.pre'}>図表\モード　<input type=checkbox name="AutoLink"$Value{'AutoLink'}>アドレスを自動リンク</small><br>　</td>
    </tr>
    <tr>
      <td></td>
      <td><input type=submit value="　　投稿する　　"><input type=reset value="リセット" onClick="return confirm('フォーム入力内容をリセットします。よろしいですか?');"><input type=submit name=clear value="クリア" onClick="return confirm('フォーム入力内容とクッキーをクリアします。よろしいですか?');">　<small><input type=checkbox name=SetCookie$Value{'SetCookie'}>個人情報を保存　　パスワード　<input type=password name=Passwd size=8 maxlength=16 value="$Value{'Passwd'}"></small></td>
    </tr>
  </table>
  </div>
</form>
<hr noshade>
$S{'Footer2'}
_EOF_

	return;
}

#/*------------------- ファイルへの記録 ----------------------------------------------*/

sub OutputMessage {

	if ($STDIN{'clear'}) {
		print "Content-type: text/html\n";
		stdio::SetCookie($S{'CookieName'},-1,-1,undef,$S{'CookiePath'}) . "\n";
		print "\n";
		$noCookie = 1;
		undef %STDIN;
		OutputSubmitForm();
	}
	if ($S{'BlockHost'}) {
		foreach (split /,/, $S{'BlockHost'}) {
			Error('403 投稿拒否',"$REMOTE_HOSTからの投稿は管理者から許可されていません。") if ($REMOTE_HOST =~ /$_/i);
		}
	}
	if ($E{'RunMode'}) {
		if ($E{'RunMode'} == 1){
			Error('403 投稿不可','閲覧モードになっているため投稿できません。');}
		elsif ($E{'RunMode'} == 2 || $E{'RunMode'} == 3) {
			if ($E{'Crypt'}){
				$AuthOK = 1 if ($STDIN{'Passwd'} && stdio::RecryptString($STDIN{'Passwd'},$E{'Passwd'}));}
			else{
				$AuthOK = 1 if ($STDIN{'Passwd'} eq $E{'Passwd'});}
			if ($E{'RunMode'} == 2) {
				Error('201 パスワード不備','マスターキーが不正です。投稿は管理者のみ可能です。') if (!$AuthOK);
			} else {
				Error('100 ファイル未検出','ユーザーファイルが存在しません。') if (!-e $UserFile);
				open(FILE, $UserFile) || Error('101 ファイル読込エラー','ユーザーファイルの読み込みができません。');
				while (<FILE>) {
					s/\r|\n//;
					@Field = split /:/;
					if ($STDIN{'Email'} eq $Field[0]) {
						if ($E{'Crypt'} && $STDIN{'Passwd'}){
							Error('201 パスワード不備','パスワードが不正です。') if (!stdio::RecryptString($STDIN{'Passwd'},$Field[1]));}
						else{
							Error('201 パスワード不備','パスワードが不正です。') if ($STDIN{'Passwd'} ne $Field[1]);}

						$userAuthOK = 1;
						last;
					}
					@Field = ();
				}
				close(FILE);
				Error('206 ユーザーID未検出','入力されたユーザーIDは存在しません。') if (!$userAuthOK);
			}
		}
	}

	#/*--- エラーのチェック		---*/
	if ($S{'ScriptUrl'} && $ENV{'HTTP_REFERER'} !~ /$S{'ScriptUrl'}/i){
		Error('204 参照元エラー','外部からの投稿はできません。');}

	elsif ($method eq 'POST' && $ENV{'REQUEST_METHOD'} ne 'POST'){
		Error('203 メソッドエラー','不正利用の可能性があります。');}

	#/*--- フォーム入力内容のチェック	---*/
	if ($STDIN{'Name'} eq ""){
		$ErrorMessage = qq|<li><b>名前</b>を入力してください。\n|;}

	elsif (length($STDIN{'Name'}) > 50){
		$ErrorMessage = qq|<li><b>名前</b>は50バイト以内で入力してください。（現在 | . length($STDIN{'Name'}) . qq|バイト）\n|;}

	if ($STDIN{'Age'} =~ /\D/ || length($STDIN{'Age'}) > 2){
		$ErrorMessage = qq|<li><b>年齢</b>は半角数字で入力してください。\n|;}

	if ($STDIN{'Email'} ne "") {
		if ($STDIN{'Email'} !~ /^[\w\+-]+@[\w\+-]+\.[\w\+\.-]+$/){
			$ErrorMessage .= qq|<li><b>メールアドレス</b>の形式が間違っています。（半角で正しく入力してください）\n|;}

		elsif (length($STDIN{'Email'}) > 50){
			$ErrorMessage .= qq|<li><b>メールアドレス</b>は50バイト以内で入力してください。（現在 | . length($STDIN{'Name'}) . qq|バイト）\n|;}
	} elsif ($STDIN{'Sendmail'}) {
		$ErrorMessage = qq|<li>返信をメール送信するため<b>メールアドレス</b>を入力してください。\n|;
	} elsif ($STDIN{'SecretEmail'}) {
		$ErrorMessage = qq|<li>匿メール送信するため<b>メールアドレス</b>を入力してください。\n|;
	}

	if ($STDIN{'Url'} ne "" && $STDIN{'Url'} ne 'http://') {
		if ($STDIN{'Url'} !~ /^http:\/\/[\w|\:\@\-]+\.[\w|\:\!\#\%\=\&\-\|\@\~\+\.\?\/\;]+$/){
			$ErrorMessage .= qq|<li><b>URL</b>の形式が間違っています。（半角で正しく入力してください）\n|;}

		elsif (length($STDIN{'Url'}) > 100){
			$ErrorMessage .= qq|<li><b>URL</b>は100バイト以内で入力してください。（現在 | . length($STDIN{'Url'}) . qq|バイト）\n|;}

	} else {
		$STDIN{'Url'} = "";
	}

	if ($STDIN{'Title'} eq ""){
		$ErrorMessage .= qq|<li><b>タイトル</b>を入力してください。\n|;}

	elsif (length($STDIN{'Name'}) > 60){
		$ErrorMessage .= qq|<li><b>タイトル</b>は60バイト以内で入力してください。（現在 | . length($STDIN{'Name'}) . qq|バイト）\n|;}


	if ($STDIN{'Comment'} eq "") {
		$ErrorMessage .= qq|<li><b>コメント</b>を入力してください。\n|;
	} else {
		$S{'ByteMax'} *= 4096;
		if (length($STDIN{'Comment'}) > $S{'ByteMax'}){
			$ErrorMessage .= qq|<li><b>コメント</b>は$S{'ByteMax'}バイト以内で入力してください。（現在 | . length($STDIN{'Comment'}) . qq|バイト）\n|;}

		elsif (($STDIN{'Comment'} =~ s/<br>/<br>/g) > 50){
			$ErrorMessage .= qq|<li><b>コメント</b>は50行以内で入力してください。（現在 | . ($STDIN{'Comment'} =~ s/<br>/<br>/g) . qq|行）\n|;}
	}

	if ($STDIN{'Passwd'} ne "") {
		if ($STDIN{'Passwd'} =~ /\W/){
			$ErrorMessage .= qq|<li><b>パスワード</b>に半角英数字以外の文字は使えません。\n|;}

		elsif (length($STDIN{'Passwd'}) < 8 || length($STDIN{'Passwd'}) > 16){
			$ErrorMessage .= qq|<li><b>パスワード</b>は8バイト以上、16バイト以内で入力してください。（現在 | . length($STDIN{'Passwd'}) . qq|バイト）\n|;}

	}

	#/*--- フォーム入力内容不備 		---*/
	if ($ErrorMessage) {
		print "Content-type: text/html\n\n";
		print qq|<html>\n|;
		print qq|<head>\n|;
		print qq|<title>$S{'Title'} [フォーム入力ミス]</title>\n|;
		print qq|</head>\n|;
		print qq|<body $S{'Body'}>\n|;
		print qq|<img src="$Script?error" width=28 height=28 alt="&lt;!&gt;"><font size=5><b> フォーム入力ミス</b></font>\n|;
		print qq|<hr size=1 width=65% align=left>\n|;
		print qq|<p>　フォームの入力内容に入力漏れ、指定文字数超過等の不備があったため、投稿処理は一旦中断されました。検出された該当箇所をもう一度ご確認の上、再試行してみてください。繰り返し、エラーメッセージが表\示される場合は、このサイトの管理者に連絡してください。</p>\n|;
		print qq|<ul>\n|;
		print qq|$ErrorMessage|;
		print qq|</ul>\n|;
		print qq|<hr noshade>\n|;
		&OutputWriteForm(%STDIN);
		print qq|</body>\n|;
		print qq|</html>\n|;
		exit(0);
	}

	@Record = stdio::ReadFile($DataFile, 0, 0, $E{'UseLock'});
	Error('100 ファイル未検出','データファイルが存在しません。') if ($Record[0] == -1 && $STDIN{'Parent'});
	Error('101 ファイル読込エラー','データファイルの読み込みができません。') if (!$Record[1] && $STDIN{'Parent'});
	Error('110 排他制御中','只今、混雑しています。時間をおいて再試行してください。') if ($Record[0] == -2);

	if ($STDIN{'Passwd'} && $E{'Crypt'}){
		$Passwd = stdio::CryptString($STDIN{'Passwd'});}

	else{
		$Passwd = $STDIN{'Passwd'};}

	$STDIN{'Comment'}  =~ s/<br><br><br>/<br>/gi;
	$STDIN{'AutoLink'} = $STDIN{'AutoLink'} ? 1 : "";
	$STDIN{'MsgType'}  = 'normal' if ($STDIN{'MsgType'} ne 'pre' && $STDIN{'MsgType'} ne 'nobr');
	$STDIN{'Sex'} = ($STDIN{'Sex'} eq 'male' || $STDIN{'Sex'} eq 'female') ? $STDIN{'Sex'} : undef;

	#/*--- 初めての投稿の場合	---*/
	if (!$Record[0] || $Record[0] == -1) {
		$Record[0] =
			  'Version='	. $Version	. "\t"
			. 'Start='	. time		. "\t"
			. 'Newcode='	. '1'		. "\t"
			. 'Tree='	. '1'		. "\t"
			. 'Lines='	. '2'		. "\t"
			. "\n";

		$FileHead{'Newcode'} = 1;

	#/*---	それ以外の場合	---*/
	} else {
		%Field = stdio::ReadData(split /\t/, $Record[1]);
		if ($Field{'Comment'} eq $STDIN{'Comment'}) {
			undef @Record;
			print "Content-type: text/html\n\n";
			return;
		}
		if (!$AuthOK && $S{'WaitTime'} && $ENV{'REMOTE_ADDR'} eq $Field{'Addr'}) {
			if (time - $Field{'Time'} < $S{'WaitTime'}) {
				Error('200 セキュリティーエラー',"$S{'WaitTime'}秒以内の連続投稿はできません。時間をおいて再試行してください。");
			}
		}
		%Field = ();
		%FileHead = stdio::ReadData(split /\t/, $Record[0]);
		$FileHead{'Newcode'} ++;
		$FileHead{'Tree'} ++ if ($STDIN{'Parent'} eq "");
		$FileHead{'Lines'} = $#Record + 2;

		$Record[0] =
			  'Version='	. $FileHead{'Version'}	. "\t"
			. 'Start='	. $FileHead{'Start'}	. "\t"
			. 'Newcode='	. $FileHead{'Newcode'}	. "\t"
			. 'Tree='	. $FileHead{'Tree'}	. "\t"
			. 'Lines='	. $FileHead{'Lines'}	. "\t"
			. "\n";
	}

	$STDIN{'Root'} = $FileHead{'Newcode'} if (!$STDIN{'Root'});

	#/*--- フィールドを統括	---*/
	unshift(@Record,
		  'Code='	. $FileHead{'Newcode'}	. "\t"
		. 'Time='	. time			. "\t"
		. 'Name='	. $STDIN{'Name'}	. "\t"
		. 'Email='	. $STDIN{'Email'}	. "\t"
		. 'SecretEmail='. $STDIN{'SecretEmail'}	. "\t"
		. 'Url='	. $STDIN{'Url'}		. "\t"
		. 'Age='	. $STDIN{'Age'}		. "\t"
		. 'Sex='	. $STDIN{'Sex'}		. "\t"
		. 'Title='	. $STDIN{'Title'}	. "\t"
		. 'Count='	. '0'			. "\t"
		. 'Comment='	. $STDIN{'Comment'}	. "\t"
		. 'MsgType='	. $STDIN{'MsgType'}	. "\t"
		. 'AutoLink='	. $STDIN{'AutoLink'}	. "\t"
		. 'Passwd='	. $Passwd		. "\t"
		. 'Parent='	. $STDIN{'Parent'}	. "\t"
		. 'Reply='	. ""			. "\t"
		. 'Root='	. $STDIN{'Root'}	. "\t"
		. 'Sendmail='	. $STDIN{'Sendmail'}	. "\t"
		. 'Host='	. $REMOTE_HOST		. "\t"
		. 'Addr='	. $REMOTE_ADDR		. "\t"
		. 'Agent='	. $HTTP_USER_AGENT	. "\t"
		. "\n"
	);
	unshift(@Record, splice(@Record, 1, 1));

	#/*--- 返信の場合		---*/
	if ($STDIN{'Parent'} ne "") {

		for ($i = 1; $i <= $#Record; $i ++) {
			%Field = stdio::ReadData(split /\t/, $Record[$i]);
			if ($Field{'Code'} == $STDIN{'Parent'}) {
				Error('406 パラメーターエラー','パラメーターの値が不正です。') if ($Field{'Root'} != $STDIN{'Root'});
				if ($Field{'Reply'}){
					$Field{'Reply'} .= ':' . $FileHead{'Newcode'};}

				else{
					$Field{'Reply'} = $FileHead{'Newcode'};}

				$find = 1;
				last;
			}
		}
		Error('120 レコード未検出','返信しようとしている記事は存在しません。') if (!$find);

		$Record[$i] =
			  'Code='	. $Field{'Code'}	. "\t"
			. 'Time='	. $Field{'Time'}	. "\t"
			. 'Name='	. $Field{'Name'}	. "\t"
			. 'Email='	. $Field{'Email'}	. "\t"
			. 'SecretEmail='. $Field{'SecretEmail'}	. "\t"
			. 'Url='	. $Field{'Url'}		. "\t"
			. 'Age='	. $Field{'Age'}		. "\t"
			. 'Sex='	. $Field{'Sex'}		. "\t"
			. 'Title='	. $Field{'Title'}	. "\t"
			. 'Count='	. $Field{'Count'}	. "\t"
			. 'Comment='	. $Field{'Comment'}	. "\t"
			. 'MsgType='	. $Field{'MsgType'}	. "\t"
			. 'AutoLink='	. $Field{'AutoLink'}	. "\t"
			. 'Passwd='	. $Field{'Passwd'}	. "\t"
			. 'Count='	. $Field{'Count'}	. "\t"
			. 'Parent='	. $Field{'Parent'}	. "\t"
			. 'Reply='	. $Field{'Reply'}	. "\t"
			. 'Root='	. $Field{'Root'}	. "\t"
			. 'Sendmail='	. $Field{'Sendmail'}	. "\t"
			. 'Host='	. $Field{'Host'}	. "\t"
			. 'Addr='	. $Field{'Addr'}	. "\t"
			. 'Agent='	. $Field{'Agent'}	. "\t"
			. "\n";
	}

	#/*--- ファイルのロック/入出力	---*/
	Error('110 排他制御中','只今混雑しています。時間をおいて再試行してください。') if (!stdio::LockCheck($DataFile,$E{'UseLock'}));
	$lockResult = stdio::FileLock($DataFile,$E{'UseLock'},@Record);
	if ($lockResult == -1){
		Error('603 シンボリックリンク不可','このサーバーではシンボリックリンクが使えません。');}

	elsif ($lockResult == 0){
		Error('102 ファイル書込エラー','ファイルへの書き込みができません。');}

	#/*--- 自動バックアップ		---*/
	if ($S{'AutoBackup'} && (($#Record - 1) % $S{'AutoBackup'} == 0)) {
		if (open(FILE, ">$BackupFile")) {
			print FILE @Record;
			close(FILE);
		}
	}

	#/*--- メール送信処理		---*/
	if ($sendmail) {
		if ($STDIN{'Parent'}) {
			for (1 .. $#Record) {
				%Field = stdio::ReadData(split /\t/, $Record[$_]);
				if ($STDIN{'Parent'} == $Field{'Code'} && $Field{'Sendmail'}) {
					push (@MAIL, $Field{'Email'});
					last;
				}
				%Field = ();
			}
		}
		push(@MAIL, $STDIN{'Email'}) if ($STDIN{'Sendmail'});
		push(@MAIL, $S{'MasterEmail'}) if ($S{'MasterEmail'} =~ /^[\w\+-]+@[\w\+-]+\.[\w\+\.-]+$/i && $S{'SendMail'});
		$STDIN{'Comment'} =~ s/<br>/\n/g;
		$STDIN{'Comment'} =~ s/&lt;/</g;
		$STDIN{'Comment'} =~ s/&gt;/>/g;
		$STDIN{'Comment'} =~ s/&amp;/&/g;
		$STDIN{'Comment'} =~ s/&quot;/"/g;
		$STDIN{'Comment'} =<<_EOF_;

このメールは$S{'Title'}に投稿された記事を送信しています。

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

[投 稿 日] $TimeNow
[ホ ス ト] $REMOTE_HOST
[アドレス] $REMOTE_ADDR

[投 稿 者] $STDIN{'Name'}
[Ｅメール] $STDIN{'Email'}
[Ｕ Ｒ Ｌ] $STDIN{'Url'}
[タイトル] $STDIN{'Title'}

$STDIN{'Comment'}

---------------------------------------------------------------------
* この記事に対する返信を投稿する場合は以下のURLから行って下さい。
   http://$ENV{'SERVER_NAME'}$ENV{'SCRIPT_NAME'}?res=$FileHead{'Newcode'}
---------------------------------------------------------------------
_EOF_

		#/*--- メール送信処理		---*/
		foreach (@MAIL) {
			stdio::SendMail($sendmail,$_,undef,undef,$STDIN{'Email'},undef,"[$FileHead{'Newcode'}] $STDIN{'Title'}",$STDIN{'Comment'});
		}
	}

	print "Content-type: text/html\n";
	if ($STDIN{'SetCookie'}) {
		$STDIN{'Name'}  =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
		$STDIN{'Email'} =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
		$STDIN{'Url'}   =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
		stdio::SetCookie($S{'CookieName'},"Name:$STDIN{'Name'}&Email:$STDIN{'Email'}&Url:$STDIN{'Url'}&Sex:$STDIN{'Sex'}&Age:$STDIN{'Age'}&Passwd:$STDIN{'Passwd'}",$S{'CookieExpires'},undef,$S{'CookiePath'}) . "\n";
	}
	print "\n";
	undef %STDIN;
	undef @Record;
}

#/*------------------- 記事の削除 ---------------------------------------------------*/

sub DeleteMessages {

	#/*--- パスワードが未入力	---*/
	Error('405 フォーム入力ミス','パスワードを入力して下さい。') if ($STDIN{'Passwd'} eq "");

	if ($E{'Crypt'}){
		$AuthOK = 1 if (stdio::RecryptString($STDIN{'Passwd'},$E{'Passwd'}));}

	else{
		$AuthOK = 1 if ($STDIN{'Passwd'} eq $E{'Passwd'});}

	if ($STDIN{'adminMode'}) {
		if ($AuthOK){
			OutputPasswordSetForm();}
		else{
			Error('201 パスワード不備','マスターキーが不正です。');}
	}

	@Record = stdio::ReadFile($DataFile, 0, 0, $E{'UseLock'});
	Error('110 排他制御中','只今混雑しています。時間をおいて再試行してください。') if ($Record[0] == -2);
	Error('100 ファイル未検出','データファイルが存在しません。') if ($Record[0] == -1);
	Error('101 ファイル読込エラー','データファイルの読み込みができません。') if ($Record[0] == 0 && !$Record[1]);
	Error('120 レコード未検出','レコードが存在しません。') if (!$Record[1]);

	#/*--- マスタキーと不一致	---*/
	if (!$AuthOK) {
		Error('201 パスワード不備','マスターキーが不正です。一括削除は管理者のみ可能です。') if ($STDIN{'mode'} eq 'deleteTree');
		for (1 .. $#Record) {
			%Field = stdio::ReadData(split /\t/, $Record[$_]);
			if ($Field{'Code'} == $STDIN{'Code'}) {
				Error('120 削除不可','この記事は既に削除されています。') if ($Field{'Title'} eq '<DELETED>');
				Error('409 削除不可','レスが付いている記事の投稿者削除はできません。') if ($Field{'Reply'} && $S{'NoDelete'});
				Error('409 削除不可','この記事の投稿者削除はできません。') if ($Field{'Passwd'} eq "");

				if ($E{'Crypt'}) {
					if (!stdio::RecryptString($STDIN{'Passwd'},$Field{'Passwd'})) {
						Error('201 パスワード不備','パスワードが不正です。');
					}
				} else {
					if ($STDIN{'passwd'} ne $Field{'passwd'}) {
						Error('201 パスワード不備','パスワードが不正です。');
					}
				}

				$Record[$_] =
					  'Code='	. $Field{'Code'}	. "\t"
					. 'Time='	. $Field{'Time'}	. "\t"
					. 'Title='	. '<DELETED>'		. "\t"
					. 'Parent='	. $Field{'Parent'}	. "\t"
					. 'Reply='	. $Field{'Reply'}	. "\t"
					. 'Root='	. $Field{'Root'}	. "\t"
					. "\n";
				$j = 1;
				last;
			}
			%Field = ();
		}

	#/*--- 管理者用パスワードと一致		---*/
	} else {
		@Record = stdio::ReadFile($DataFile);

		#/*--- ツリーそのものの削除	---*/
		if ($STDIN{'mode'} eq 'deleteTree') {
			for (1 .. $#Record) {
				%Field = stdio::ReadData(split /\t/, $Record[$_]);
				if ($Field{'Root'} == $STDIN{'Code'}) {
					$deleteTitle = $Field{'Title'} if ($Field{'Code'} == $STDIN{'Code'});
					undef $Record[$_];
					$j ++;
				}
				%Field = ();
			}
			%FileHead = stdio::ReadData(split /\t/, $Record[0]);
			$FileHead{'Tree'} --;
			$FileHead{'Lines'} -= $j;
			$Record[0] =
				  'Version='	. $FileHead{'Version'}	. "\t"
				. 'Start='	. $FileHead{'Start'}	. "\t"
				. 'Newcode='	. $FileHead{'Newcode'}	. "\t"
				. 'Tree='	. $FileHead{'Tree'}	. "\t"
				. 'Lines='	. $FileHead{'Lines'}	. "\t"
				. "\n";

			$Field{'Title'} = "ルート記事（$deleteTitle）以下";

		} else {
			for (1 .. $#Record) {
				%Field = stdio::ReadData(split("\t", $Record[$_]));
				if ($Field{'Code'} == $STDIN{'Code'}) {
					Error('120 削除不可','この記事は既に削除されています。') if ($Field{'Title'} eq '<DELETED>');
					$Record[$_] =
						  'Code='	. $Field{'Code'}	. "\t"
						. 'Time='	. $Field{'Time'}	. "\t"
						. 'Title='	. '<DELETED>'		. "\t"
						. 'Parent='	. $Field{'Parent'}	. "\t"
						. 'Reply='	. $Field{'Reply'}	. "\t"
						. 'Root='	. $Field{'Root'}	. "\t"
						. "\n";
					$j = 1;
					last;
				}
				%Field = ();
			}
		}
	}
	Error('120 削除失敗','指定されたコードの記事は存在しません。') if (!$j);

	#/*--- ファイルのロック/入出力	---*/
	Error('110 排他制御中','只今混雑しています。時間をおいて再試行してください。') if (!stdio::LockCheck($DataFile,$E{'UseLock'}));
	$lockResult = stdio::FileLock($DataFile,$E{'UseLock'},@Record);
	if ($lockResult == -1){
		Error('603 シンボリックリンク不可','このサーバーではシンボリックリンクが使えません。');}

	elsif ($lockResult == 0){
		Error('102 ファイル書込エラー','ファイルへの書き込みができません。');}

	Error('削除完了','記事を削除しました。',"指定された記事[$Field{'Title'}]をデータベースより削除しました。");
}

#/*------------------- キーワード検索窓表示 -----------------------------------------*/

sub OutuputSearchForm {
	if ($STDIN{'mhmode'} == 1){
		$mhmodeChecked1 = ' checked';}
	elsif ($STDIN{'mhmode'} == 2){
		$mhmodeChecked2 = ' checked';}
	else{
		$mhmodeChecked0 = ' checked';}

	if ($STDIN{'match'} eq 'Name'){
		$NameChecked = ' selected';}
	elsif ($STDIN{'match'} eq 'Title'){
		$TitleChecked= ' selected';}
	elsif ($STDIN{'match'} eq 'Email'){
		$EmailChecked= ' selected';}
	elsif ($STDIN{'match'} eq 'Url'){
		$UrlChecked  = ' selected';}
	elsif ($STDIN{'match'} eq 'Comment'){
		$CommentChecked=' selected';}

	if ($STDIN{'when'} eq 'ge'){
		$geChecked = ' selected';}
	elsif ($STDIN{'when'} eq 'le'){
		$leChecked = ' selected';}
	elsif ($STDIN{'when'} eq 'eq'){
		$eqChecked = ' selected';}


	print <<_EOF_;

<a name=search></a>
<hr noshade>
<form action="$Script" name="searchForm">
  <input type=hidden name="mode" value="seek">
  <table border=1 cellspacing=0 cellpadding=2>
    <tr>
      <td> 検索キー <input name=keyword size=25 value="$STDIN{'keyword'}" maxlength=60>　<input type=radio value=0 name=mhmode$mhmodeChecked0>AND　<input type=radio name=mhmode value=1$mhmodeChecked1>OR　<input type=radio value=2 name=mhmode$mhmodeChecked2>検索式　</td>
      <td rowspan=2>　<input type=submit value="検索開始"><input type=reset value="×">　</td>
    </tr>
    <tr>
      <td> <select name=match>
        <option value=all>全ての情報
        <option value=Name$NameChecked>投稿者
        <option value=Title$TitleChecked>タイトル
        <option value=Email$EmailChecked>メールアドレス
        <option value=Url$UrlChecked>URL
        <option value=Comment$CommentChecked>コメント
      </select>から<select name=year>
        <option value=2000 selected>2000年
        <option value=2001>2001年
	<option value=2002>2002年
	<option value=2003>2003年
      </select><select name="month">
_EOF_

	for (1 .. 12) {
		if ($_ == $STDIN{'month'}) {
			print qq|        <option value=$_ selected>$_月\n|;
		} elsif (!$STDIN{'month'} && $_ == (gmtime(time + $S{'TimeZone'} * 3600))[4] + 1) {
			print qq|        <option value=$_ selected>$_月\n|;
		} else {
			print qq|        <option value=$_>$_月\n|;
		}
	}
	print qq|      </select><select name="day">\n|;
	for (1 .. 31) {
		if ($_ == $STDIN{'day'}) {
			print qq|        <option value=$_ selected>$_日\n|;
		} elsif (!$STDIN{'day'} && $_ == (gmtime(time + $S{'TimeZone'} * 3600))[3]) {
			print qq|        <option value=$_ selected>$_日\n|;
		} else {
			print qq|        <option value=$_>$_日\n|;
		}
	} 
	print <<_EOF_;
      </select> - <select name=when>
        <option value=0>指定なし
        <option value=ge$geChecked>以降
        <option value=le$leChecked>以前
        <option value=eq$eqChecked>当日
      </select>　</td>
    </tr>
  </table>
</form>
<form action="$Script" method=$method><input type=hidden name=mode value=delete><input type=hidden name=adminMode value=1>
  <table border=1 cellpadding=3 cellspacing=0>
    <tr>
      <td>パスワード　<input type=password name=Passwd size=10 maxlength=16><input type=submit value="管理"></td>
    </tr>
  </table>
</form>

_EOF_
	return;
}

#/*------------- 記事の全体検索 ---------------------------------------------*/

sub SearchMessages {
	if ($STDIN{'keyword'} eq "") {
		print "Content-Type: text/html\n\n";
		return;
	}

	@Record = stdio::ReadFile($DataFile);
	Error('110 排他制御中','只今混雑しています。時間をおいて再試行してください。') if ($Record[0] == -2);
	Error('100 ファイル未検出','データファイルが存在しません。') if ($Record[0] == -1);
	Error('101 ファイル読込エラー','データファイルの読み込みができません。') if ($Record[0] == 0 && !$Record[1]);

	$STDIN{'keyword'} =~ s/&amp;/&/g;
	$tmpData = shift(@Record);

	#/*--- 日付の限定して検索	---*/
	if ($STDIN{'when'}) {
		$timeNow = sprintf("%d%02d%02d",$STDIN{'year'},$STDIN{'month'},$STDIN{'day'});
		$i = 0;
		foreach (@Record) {
			%Field = stdio::ReadData(split /\t/);
			@Time = gmtime($Field{'Time'} + $S{'TimeZone'} * 3600);
			$TimeInp = sprintf("%d%02d%02d",$Time[5]+1900,$Time[4]+1,$Time[3]);
			if ($STDIN{'when'} eq 'eq' && $timeNow == $TimeInp) {
				$Record2[$i] = $_;
				$i ++;
			} elsif ($STDIN{'when'} eq 'ge' && $timeNow <= $TimeInp) {
				$Record2[$i] = $_;
				$i ++;
			} elsif ($STDIN{'when'} eq 'le' && $timeNow >= $TimeInp) {
				$Record2[$i] = $_;
				$i ++;
			}
			%Field = ();
		}
		@Record = @Record2;
		undef @Record2;
	}

	#/*--- 検索対象を限定して検索	---*/
	if ($STDIN{'match'} ne 'all') {
		$i = 0;
		foreach (@Record) {
			%Field = stdio::ReadData(split /\t/);
			$Ref = \$Record[$i];
			push(@SearchRecord, "$Field{'Code'}\t$Field{$STDIN{'match'}}\t$i");
			%Field = ();
			$i ++;
		}
		@SearchRecord = stdio::SearchRecord($STDIN{'keyword'},$STDIN{'mhmode'},0,@SearchRecord);

		if (@SearchRecord) {
			$i = 0;
			foreach (@SearchRecord) {
				($Code,$Name,$Code2) = split "\t";
				$Record2[$i] = $Record[$Code2];
				$i ++;
			}
		}
		@Record = @Record2;

	#/*--- 通常検索の場合		---*/
	} else {
		@Record = stdio::SearchRecord($STDIN{'keyword'},$STDIN{'mhmode'},0,@Record);
	}
	unshift(@Record, $tmpData);

	print "Content-type: text/html\n\n";
	if ($Record[1]){
		$searchResult = "<hr noshade>\n<b>$STDIN{'keyword'}</b>で検索の結果 <b>$#Record</b>件がデータベースに存在しました。\n";
	} else {
		$searchResult = "<hr noshade>\n<b>$STDIN{'keyword'}</b>で検索の結果 該当する記事はデータベースに存在しませんでした。\n";
		$STDIN{'keyword'} =~ s/&/&amp;/g;
		$noMatch = 1;
		OutputListView();
	}

	$STDIN{'keyword'} =~ s/&/&amp;/g;
	$keyword = $STDIN{'keyword'};
	$keyword =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
	$QueryString  = "&amp;mode=seek&amp;keyword=$keyword&amp;mhmode=$STDIN{'mhmode'}&amp;match=$STDIN{'match'}&amp;year=$STDIN{'year'}&amp;month=$STDIN{'month'}&amp;day=$STDIN{'day'}&amp;when=$STDIN{'when'}";

	$STDIN{'start'} = 1 if ($STDIN{'start'} < 1 || $STDIN{'start'} > $#Record);

	$FileHead{'Lines'} = $#Record;
	shift(@Record);
	@Record = splice(@Record, $STDIN{'start'}-1, $S{'PageMax'});
	OutputListView();

}

###############################################################################

exit(0);

#/*------------- 環境設定ファイル読み込み -----------------------------------*/

sub ReadEnvFile {
	open(FILE, $_[0]) || Error('101 ファイル読込エラー','環境設定ファイルの読み込みができません。');
	while(<FILE>) {
		s/\r|\n//g;
		($Key,$Value) = split /\t/;
		$E{$Key} = $Value;
	}
	close(FILE);
	return %E;
}

#/*------------- パスワード設定フォーム出力 ---------------------------------*/

sub OutputPasswordSetForm {
	if (-s $EnvFile){
		%E = ReadEnvFile($EnvFile);}

	if ($E{'RunMode'} == 1){
		$checkedRunMode1 = ' checked';}
	elsif ($E{'RunMode'} == 2){
		$checkedRunMode2 = ' checked';}
	elsif ($E{'RunMode'} == 3){
		$checkedRunMode3 = ' checked';}
	else{
		$checkedRunMode0 = ' checked';}

	print "Content-type: text/html\n\n";
	print <<_EOF_;

<html>
<head>
<title>セットアップ</title>
</head>
<body  bgcolor=FFFFEE onLoad="document.setupForm.newPasswd.focus();">
<font size=6>System Setup</font> - <b>セットアップ</b>
<hr noshade size=4 width=610 align=left>
<p>　システムのセットアップを開始します。セットアップは初めて設置る時、サーバーの仕様が変更された時、設置場所を変更した時、パスワードを変更する時に行います。にセットアップでは、マスターキー（管理者パスワード）を設定します。あなたのサーバーから環境情報を自動的に検出します。</p>
$ErrorMessage
<form method=POST action="$Script" name=setupForm>
  <input type=hidden name="mode" value="setup"><input type=hidden name="Passwd" value="$STDIN{'Passwd'}">
  <table border=0 width=450>
    <tr>
      <td><b>■ マスターキー</b>
        <hr size=1>
        <blockquote>
          <input type=password name="newPasswd" size=20 maxlength=16><br>
          <input type="password" name="newPasswd_retype" size=20 maxlength=16>（再入力）<ul><small>
            <li>新規セットアップ時、マスターキー変更時に入力します。
            <li>マスターキーを設定します。これは記事の削除やメンテナンスに使います。
            <li>マスターキーは8〜16文字の半角英数字（大文字小文字区別）を使ってください。
            <li>メールアドレス、名前、生年月日等の推測されやすいものは避けましょう。<br>　
          </small></ul>
        </blockquote>
        <b>■ 運用モード</b>
        <hr size=1>
        <blockquote>
          <input type=radio name=RunMode value=0$checkedRunMode0> 通常モード （誰でも閲覧・投稿可）<br>
          <input type=radio name=RunMode value=1$checkedRunMode1> 閲覧モード （閲覧のみ可）<br>
          <input type=radio name=RunMode value=2$checkedRunMode2> 日記モード （投稿は管理者のみ可）<br>
          <input type=radio name=RunMode value=3$checkedRunMode3> 認証モード （投稿には認証要）<ul><small>
            <li>日記モードでは投稿時にマスターキーを入力します。
            <li>認証モードはユーザーファイルが別に必要となります。<br>　
          </small></ul>
        </blockquote>
      </td>
    </tr>
    <tr>
      <td align=center>　<br><input type=submit value="　　設定反映　　"><input type=reset value="リセット"></td>
    </tr>
  </table>
</form>
</body>
</html>

_EOF_

	exit(0);
}

#/*------------- サーバー環境情報設定 ---------------------------------------*/

sub SetupPassword {
	if (-s $EnvFile && $STDIN{'Passwd'}) {
		%E = ReadEnvFile($EnvFile);
		if ($E{'Crypt'}) {
			Error('201 パスワード不備','パスワードが不正です。') if (!stdio::RecryptString($STDIN{'Passwd'},$E{'Passwd'}));
		} elsif ($E{'Passwd'} eq $STDIN{'Passwd'}) {
			Error('201 パスワード不備','パスワードが不正です。');
		}
		$STDIN{'newPasswd_retype'} = $STDIN{'newPasswd'} = $STDIN{'Passwd'} if ($STDIN{'newPasswd'} eq "");
		undef %E;
	}
	if ($STDIN{'newPasswd'} ne "") {
		if ($STDIN{'newPasswd'} =~ /\W/) {
			$ErrorMessage = qq|  <li><b>パスワード</b>に半角英数字以外の文字は使えません。\n|;
		} elsif (length($STDIN{'newPasswd'}) < 8 || length($STDIN{'newPasswd'}) > 16) {
			$ErrorMessage = qq|  <li><b>パスワード</b>は8バイト以上、16バイト以内で入力してください。（現在 | . length($STDIN{'newPasswd'}) . qq|バイト）\n|;
		} elsif ($STDIN{'newPasswd'} ne $STDIN{'newPasswd_retype'}) {
			$ErrorMessage = qq|  <li><b>パスワードの確認</b>（再入力されたもの）が一致しません。\n|;
		}
	} elsif (!-e $EnvFile && !$STDIN{'Passwd'}) {
		$ErrorMessage = qq|  <li><b>パスワード</b>を入力してください。\n|;
	}
	if ($ErrorMessage) {
		$ErrorMessage = "<ul>\n" . $ErrorMessage . "</ul>\n";
		OutputPasswordSetForm();
	}
	$E{'Passwd'} = stdio::CryptString($STDIN{'newPasswd'});
	if ($E{'Passwd'} != -1) {
		$E{'Crypt'} = 1 if (stdio::RecryptString($STDIN{'newPasswd'},$E{'Passwd'}) == 1);
	}
	$Passwd = $STDIN{'newPasswd'} if ($E{'Crypt'} != 1);

	$E{'Symlink'} = eval { symlink("",""); 1; };
	$E{'Rename'}  = eval { rename("",""); 1; };

	if ($E{'Symlink'} && $E{'Rename'}){
		$E{'UseLock'} = 2;}

	elsif ($E{'Rename'}){
		$E{'UseLock'} = 1;}

	else{
		$E{'UseLock'} = 0;}

	$E{'Crypt'}   = $E{'Crypt'}   ? 1 : 0;
	$E{'Rename'}  = $E{'Rename'}  ? 1 : 0;
	$E{'Symlink'} = $E{'Symlink'} ? 1 : 0;
	$E{'RunMode'} = ($STDIN{'RunMode'} >= 0 && $STDIN{'RunMode'} <= 3) ? $STDIN{'RunMode'} : 0;

	open(FILE, ">$EnvFile") || Error('102 ファイル書込エラー','ファイルへの書き込みができません。');
	print FILE "Crypt\t"   . $E{'Crypt'}	. "\n";
	print FILE "Symlink\t" . $E{'Symlink'}	. "\n";
	print FILE "Rename\t"  . $E{'Rename'}	. "\n";
	print FILE "UseLock\t" . $E{'UseLock'}	. "\n";
	print FILE "Passwd\t"  . $E{'Passwd'}	. "\n";
	print FILE "RunMode\t" . $E{'RunMode'}	. "\n";
	close(FILE);
	return;
}

#/*------------- エラーサイン画像出力 ---------------------------------------*/

sub ErrorSign {
	@array = (
	'47','49','46','38','39','61','1c','00','1c','00','a1','00','00','00','00','00','ff','00','00','ff',
	'ff','ff','bf','bf','bf','21','f9','04','01','00','00','03','00','2c','00','00','00','00','1c','00',
	'1c','00','00','02','68','9c','8f','a9','cb','18','1f','9a','4c','30','ce','59','df','95','d9','6e',
	'd5','69','1f','15','8e','4e','28','9a','68','fa','65','82','90','a9','d5','1b','b7','f3','0b','57',
	'36','24','00','40','0e','d9','b8','7a','3f','20','8b','31','f4','d1','74','9c','1b','11','57','43',
	'3a','95','cb','a0','94','87','a3','56','8f','87','e1','4b','6b','f4','9c','b0','b8','32','94','39',
	'7e','98','c1','61','12','39','5b','2c','47','07','5e','b3','3d','ba','ca','97','e8','fa','be','c6',
	'0f','18','08','c8','27','88','32','50','00','00','3b');

	print "Content-type: image/gif\n";
	print "Content-length: 151\n";
	print "\n";
	binmode(STDOUT);
	foreach (@array) {
		print pack('C*',hex($_));
	}
	exit(0);
}

#/*------------- エラー発生時の処理 -----------------------------------------*/

sub Error {
	@ErrorMessage = @_;
	$ErrorMessage[0] = '000 システムエラー'				    if (!$ErrorMessage[0]);
	$ErrorMessage[1] = '原因不明のエラー発生により強制終了されました。' if (!$ErrorMessage[1]);
	$ErrorMessage[2] = '<p>' . $ErrorMessage[2] . '</p>'		    if  ($ErrorMessage[2]);
	$ErrorMessage[2] = qq|  <p>　このプログラムはリクエスト処理中にエラーが発生したため、処理を中断しました。エラーの発生原因として、リクエスト内容の不備、アクセス権が与えられていない、誤った設定がなされている、あるいは突発的なサーバーエラー等の可能\性が考えられます。<br>\n|
			 . qq|　表\示されたエラーメッセージをご確認の上、再試行してみてください。ブラウザでリロードすることで再試行できます。繰り返し、エラーメッセージが表\示される場合は、このサイトの管理者に連絡してください。</p>\n|
			 if (!$ErrorMessage[2]);

	print "Content-type: text/html\n\n";
	print <<_EOF_;

<html>
<head>
<title>$S{'Title'} [$ErrorMessage[0]]</title>
<meta http-equiv="Pragma" content="no-cache">
$S{'StyleSheet'}</head>
<body $S{'Body'}>
<img src="$Script?error" width=28 height=28 alt="&lt;!&gt;"><font size=5><b> $ErrorMessage[0]</b></font>
<hr size=1 width=65% align=left>
<blockquote>
  <h3>$ErrorMessage[1]</h3>
  $ErrorMessage[2]
  <p align=center><a href="javascript:history.back(1)">前ページへ戻る</a></p>
</blockquote>
<hr noshade>
</body>
</html>

_EOF_

	exit(1);
}

sub sigexit {
	if (-e $stdio::lockfile) { unlink($stdio::lockfile); }
	if (-e $stdio::tempfile) { unlink($stdio::tempfile); }
	exit(1);
}
