#!/usr/local/bin/perl

#┌─────────────────────────────────
#│  WEB FORUM v3.24 (2002/02/04)
#│  Copyright(C) KENT WEB 2002
#│  webmaster@kent-web.com
#│  http://www.kent-web.com/
#└─────────────────────────────────
$ver = 'Web Forum v3.24';
#┌─────────────────────────────────
#│[ 注意事項 ]
#│ 1. このスクリプトはフリーソフトです。このスクリプトを使用した
#│    いかなる損害に対して作者は一切の責任を負いません。
#│ 2. 設置に関する質問はサポート掲示板にお願いいたします。
#│    直接メールによる質問は一切お受けいたしておりません。
#└─────────────────────────────────
#
# [設置例] かっこ内はパーミッション
#
#    public_html / index.html (ホームページ)
#       |
#       +-- bbs / wforum.cgi   [755]
#            |    wf_log.cgi   [666]
#            |    wf_admin.cgi [755]
#            |    jcode.pl     [644]
#            |    fold.pl      [644]
#            |    pastno.dat   [666] ... (過去ログ用)
#            |
#            +-- past [777] / 0001.cgi [666] ... (過去ログ用)
#            |
#            +-- lock [777] /
#

#============#
#  基本設定  #
#============#

# ライブラリ取込み
require '../jcode.pl';
require '../fold.pl';

# 掲示板タイトル名
$title = "Wonderland Forum";

# タイトルの色
$t_color = "#004080";

# タイトルの大きさ（ポイント数:スタイルシート）
$t_point = '18pt';

# タイトル／本文の文字タイプ
$t_face = 'MS UI Gothic';

# タイトル画像を使用するとき
$t_gif = "../../data/wforum/sow0/title.gif";	
$t_wid = 199;		# 画像の横サイズ（ピクセル）
$t_hgt = 33;		# 画像の縦サイズ（ピクセル）

# 本文の文字大きさ（ポイント数:スタイルシート）
$pt = '10pt';

# 最大記事数
$max = 200;

# 戻り先のＵＲＬ(index.htmlなど)
$home = "http://www.senseofwonder.org/~hasegawa/sow/wonderland.shtml";

# 壁紙・背景色・文字色など
$bground = "../../images/bg.jpg";		# 壁紙の指定
$bgcolor = "#F1F1F1";	# テキスト色
$text    = "#004080";	# 文字色
$link    = "#0000E3";	# リンク色（未訪問）
$vlink   = "#008080";	# リンク色（既訪問）
$alink   = "#DD0000";	# リンク色（訪問中）

# スクリプト名
$script = './wforum.cgi';

# ログファイル名
$logfile = '../../data/wforum/sow0/wf_log.cgi';

# 管理ファイル
$admin = './wf_admin.cgi';

# タグの許可 (0=no 1=yes)
$tagkey = 1;

# ロックファイル機構
#   0 : 行なわない
#   1 : 行なう（symlink関数式）
#   2 : 行なう（mkdir関数式）
$lockkey = 0;

# ロックファイル名
$lockfile = '../../data/wforum/sow0/wforum.lock';

# URL自動リンク (0=no 1=yes)
$autolink = 1;

# 記事の [題名] の色
$sub_color = "#DD0000";

# 記事下地の色（一括表示時等）
$tbl_color = "#FFFFFF";

# 記事にNEWマークを付ける時間
$new_time = 48;

# NEWマークの色
$new_color = "#FF80FF";

# NEWマークの表示形態
#  → 画像を使用する場合には $newmark = '<img src="./new.gif">';
#     というように IMGタグを記述してもよい
$newmark = 'new!';

# 記事NOの色
$no_color = "#800000";

# 新着記事一括表示の記事数
$sortcnt = 20;

# 頁あたりツリー表示数
$p_tree = 10;

# リストに表示する「記事タイトル」の最大長（文字数：半角文字換算）
$sub_length = 40;

# メールアドレスの入力を必須 (0=no 1=yes)
$in_email = 1;

# レスがついたらツリー毎トップへ移動 (0=no 1=yes)
$top_sort = 1;

# レスは下から順に付ける (0=no 1=yes)
$bot_res = 1;

# 引用部色変更
#  1) ここに色指定を行うと「引用部」を色変更します
#  2) 必ずタグは禁止処理にしてください ($tagkey=1;)
#  3) この機能を使用しない場合は何も記述しないで下さい ($refcolor="";)
$refcolor = "#804000";

# methodの形式 (POST/GET)
$method = 'POST';

# 記事の更新は「method=POST」限定（セキュリティ対策）
#  0 : no
#  1 : yes
$MethPost = 1;

# 投稿があるとメール通知する : sendmail必須
#  0 : 通知しない
#  1 : 通知する（自分の記事は送信しない）
#  2 : 通知する（自分の記事も送信する）
$mailing = 2;

# メール通知する際のメールアドレス
$mailto = 'sow@freeml.com';

# sendmailパス（メール通知する時）
$sendmail = '/usr/sbin/sendmail';

# ツリーのヘッダー記号
$treehead = "★";

# 過去ログ機能 (0=no 1=yes)
$pastkey = 1;

# 過去ログカウントファイル
$nofile = '../../data/wforum/sow0/pastno.dat';

# 過去ログのディレクトリ（最後は / で閉じる)
$pastdir = '../../data/wforum/sow0/past/';

# 過去ログ１ページ当りの最大行数
#  → これを超えると自動的に次ファイルを生成します
$max_line = '650';

# アクセス制限（ホスト名を記述）
@deny = (
	'107.150.40.162',
	'27-96-63-127.ipq.jp',
	'a027.ap.plala.or.jp',
	'no-reverse-dns.net',
	'.west.hnext.alpha-net.ne.jp',
	'27-96-63-27.ipq.jp',
	'.dsn.jp',
	'flets-n-osk-2-8.dsn.jp',
	'fairy.dataforce.net',
	'.west.bflets.alpha-net.ne.jp',
	'*.proxy.xxx',
	'hosted-by.ecatel.net',
	'.osakff01.ap.so-net.ne.jp',
	'.osaka.sannet.ne.jp',
	'd-osaka.nttpc.ne.jp',
	'*.p-osaka.nttpc.ne.jp',
	'ap.yournet.ne.jp',
	'vectant.ne.jp',
	'bbexcite.jp',
	'cyberbb.ne.jp',
	'fbb.ReSET.JP',
	'cdn-ce-den-t2-01.cmc.co.denver.comcast.net',
	'218.22.246.34',
	'nodomaintransfer28.com',
	'CF059157190021.cims.jp',
	'*.iskratelecom.ru',
	'osaknt01.ap.so-net.ne.jp',
	'69.46.16.231',
	'*.kcn.ne.jp',
	'*.osaka-ip.dti.ne.jp',
	'*.ppp11.odn.ad.jp',
	'p1247-ipbf311osakakita.osaka.ocn.ne.jp',
	'*.oska.nt.adsl.ppp.infoweb.ne.jp',
	'*.osk.mesh.ad.jp',
	'*.s06.a027.ap.plala.or.jp',
	'*.ap.highway.ne.jp',
	'*.ppp.u-netsurf.ne.jp',
	'j111165.ppp.asahi-net.or.jp',
	'p2135-ipbf614osakakita.osaka.ocn.ne.jp',
	'*osakakita.osaka.ocn.ne.jp',
	'bflets-ba-west-2-27.dsn.jp',
	'*.ap.kagoya.net',
	'153.37.205.61.west.flets.alpha-net.ne.jp',
	'*.i-revonet.jp',
	'flets-a-west-8-246.dsn.jp',
	'.internetserviceteam.com',
	'bflets-ba-west-2-83.dsn.jp',
	'20.net220148188.t-com.ne.jp',
	'*.urban.ne.jp',
	'163.208.12.61.ap.zero-isp.net',
	'osk1-p118.flets.hi-ho.ne.jp',
	'112.172.12.61.ap.gmo-access.jp',
	'116.255.94.219.west.bflets.alpha-net.ne.jp',
	'ircnet.net.ru',
	'95.215.0.39',
	'.vips.gol.ne.jp',
	'.oska.nt.ftth.ppp.infoweb.ne.jp',
        '107.150.40.162',
        'HOST_NOT_DEFINED',
	'');

# 禁止ワード（URLなど)
@ngwords = (
	'adultsexporn.biz',
	'excisearch.net',
	'goldenloto.com',
	'frasesdecine',
	'9.jp',
	'703.jp',
	'href=',
	'sex',
	'home-loan',
	'rgip.org');


#============#
#  設定完了  #
#============#

# bodyタグの定義
# $body = "<body background=\"$bground\" bgcolor=\"$bgcolor\" text=\"$text\" link=\"$link\" vlink=\"$vlink\" alink=\"$alink\">\n";
$body = "<body background=\"$bground\" bgcolor=\"$bgcolor\" text=\"$text\" link=\"$link\" vlink=\"$vlink\" alink=\"$alink\">\n<IMG SRC=\"../lime/lime.cgi?page=91000&name=/cgi-bin/wforum0/wforum.cgi\" WIDTH=2 HEIGHT=2>\n";

# 基本処理を定義
&decode;
&axs_check;
if ($mode eq "regist") { &regist; }
elsif ($mode eq "form" && $in{'pview'} eq "on") { &preview; }
elsif ($mode eq "form" && $in{'pview'} ne "on") { &regist; }
elsif ($mode eq "msgview") { &msgview; }
elsif ($mode eq "allread") { &allread; }
elsif ($mode eq "new_sort") { &new_sort; }
elsif ($mode eq "usr_del") { &usr_del; }
elsif ($mode eq "usr_edt") { &usr_edt; }
elsif ($mode eq "find") { &find; }
elsif ($mode eq "howto") { &howto; }
elsif ($mode eq "past") { &past_view; }
&list_view;


#----------------#
#  アクセス制限  #
#----------------#
sub axs_check {
	# ホスト名を取得
	&get_host;

	local($flag)=0;
	foreach (@deny) {
		next if (!$_);
		s/\*/\.\*/g;
		if ($host =~ /$_/i) {
			 $flag=1;
			 last;
		}
	}
	if ($flag) {
		print "Content-type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print '<META HTTP-EQUIV="Refresh" CONTENT="0;URL=http://www.amazon.co.jp/gp/product/B003N4TQ6E?ie=UTF8&tag=aquaplanet0e-22&linkCode=as2&camp=247&creative=7399&creativeASIN=B003N4TQ6E">';
print "</head>";
print "<body></body>";
print "</html>";
		exit;
	}
}

sub chk_content {
	local($chkword) = $_[0];
	local($flag)=0;

	foreach (@ngwords) {
		next if (!$_);
		s/\*/\.\*/g;
		if ($chkword =~ /$_/i) { $flag=1; last; }
	}
	return ($flag);
}



#----------------#
#  デコード処理  #
#----------------#
sub decode {
	local($buffer, $name, $value, @pairs);

	$post_flag=0;
	if ($ENV{'REQUEST_METHOD'} eq "POST") {
		$post_flag=1;
		if ($ENV{'CONTENT_LENGTH'} > 51200) { &error("投稿量が大きすぎます"); }
		read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
	} else { $buffer = $ENV{'QUERY_STRING'}; }
	@pairs = split(/&/, $buffer);
	foreach (@pairs) {
		($name, $value) = split(/=/);

		$value =~ tr/+/ /;
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

		# S-JIS変換
		&jcode'convert(*value, "sjis", "", "z");

		# タグ処理
		if ($tagkey) { $value =~ s/<>/&lt;&gt;/g; }
		else {
			$value =~ s/&/&amp;/g;
			$value =~ s/</&lt;/g;
			$value =~ s/>/&gt;/g;
		}
		# 不要な改行を削除
		if ($name ne "message") {
			$value =~ s/\r//g;
			$value =~ s/\n//g;
		}
		$in{$name} = $value;
	}
	$mode = $in{'mode'};
	$page = $in{'page'};
	if ($page eq "") { $page = 0; }
	$in{'url'} =~ s/^http\:\/\///;
	$in{'pastlog'} =~ s/\D//g;

	# 強制改行
	if (($mode eq "form" && $in{'pview'} ne "on" && $in{'wrap'} eq "hard") || ($mode eq "regist" && $in{'wrap'} eq "hard")) {
		&get_agent;
		$bytes = $com_wid;
		if ($in{'action'} eq "res_msg") { $bytes += 2; }
		local($tmp) = '';
		while (length $in{'message'}) {
			($folded, $in{'message'}) = &fold ($in{'message'},$bytes);
			$tmp .= "$folded<br>";
		}
		$in{'message'} = $tmp;
	}
	# 改行コード処理
	$in{'message'} =~ s/\r\n/<br>/g;
	$in{'message'} =~ s/\r/<br>/g;
	$in{'message'} =~ s/\n/<br>/g;
	while ($in{'message'} =~ /<br>$/) { $in{'message'} =~ s/<br>$//g; }

	# タイムゾーンを日本時間に合わせる
	$ENV{'TZ'} = "JST-9";
}

#----------------#
#  書き込み処理  #
#----------------#
sub regist {
	# POST限定
	if ($MethPost && !$post_flag) { &error("不正なアクセスです"); }

	# フォームチェック
	if ($in{'name'} eq "" || $in{'message'} eq "")
		{ &error("名前又はメッセージに記入モレがあります"); }
	# E-Mail入力
	if ($in_email && $in{'email'} !~ /[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,5}/)
		{ &error("E-Mailの入力が不正です"); }

	$n = chk_content($in{'message'});
	if ($n > 0) {
		&after;
	}

	$n =  $in{'message'} =~ tr/\xa1-\xfe/\xa1-\xfe/;
	if ($n == 0) {
		&after;
	}

	# URL入力
#	if ($in{'no'} eq 'new' && !$in{'url'}) { &error("設置スクリプトのＵＲＬ記述は必須です"); }

	# 題名入力
	if ($in{'sub'} eq "") { &error("題名の入力モレです"); }

	# ロック処理
	&lock if ($lockkey);

	# ログファイル読み込み
	open(IN,"$logfile") || &error("Open Error : $logfile");
	@lines = <IN>;
	close(IN);

	# カウントファイルをアップ
	$count = shift(@lines);
	$count =~ s/\n//;
	if ($count == 9999) { $count = 1; } else { $count++; }

	# 二重投稿の禁止
	$flag=0;
	foreach (@lines) {
		($kno,$kre,$kx,$ktt,$kem,$kurl,$kname,$kdate,$kmsg) = split(/<>/);
		if ($in{'name'} eq $kname && $in{'message'} eq $kmsg) { $flag=1; last; }
	}
	if ($flag) { &error("二重投稿は禁止です"); }

	# クッキーを発行
	&set_cookie;

	# パスワード暗号化
	if ($in{'pwd'} ne "") { $ango = &encrypt($in{'pwd'}); }

	# 時間を取得
	$times = time;
	$date = &get_time("$times", "log");

	## --- 親記事の場合
	if ($in{'no'} eq 'new') {
		unshift (@lines,"$count<>no<>0<>$in{'sub'}<>$in{'email'}<>$in{'url'}<>$in{'name'}<>$date<>$in{'message'}<>$times<>$host<>$ango<>$in{'wrap'}<>$count<>$in{'smail'}<>0<>\n");
		@new = @lines;
	}
	## --- レス記事の場合
	else {
		## ツリーソート「あり」
	 	if ($top_sort) {
			@new=();
			@tmp=();
			$flag=0;
			foreach (@lines) {
				chop;
				($no,$reno,$lx,$t,$e,$u,$n,$d,$m,$tm,$h,$a,$w,$OYA,$smail,$res) = split(/<>/);
				if ($bot_res && $flag == 1 && $lx2 > $lx && $OYA == $in{'oya'}) {
					$flag=2;
					push(@new,"$count<>$in{'no'}<>$lx2<>$in{'sub'}<>$in{'email'}<>$in{'url'}<>$in{'name'}<>$date<>$in{'message'}<>$times<>$host<>$ango<>$in{'wrap'}<>$in{'oya'}<>$in{'smail'}<>0<>\n");
				}
				# 同一ツリーの記事を @new に配列分割（直レス）
				if ($no == $in{'no'}) {
					$res++;
					push(@new,"$no<>$reno<>$lx<>$t<>$e<>$u<>$n<>$d<>$m<>$tm<>$h<>$a<>$w<>$OYA<>$smail<>$res<>\n");
				}
				# 同一ツリーの記事を @new に配列分割
				elsif ($in{'oya'} == $OYA) { push(@new,"$_\n"); }
				# 別ツリーの記事を @tmp に配列分割
				else { push(@tmp,"$_\n"); }

				if ($no == $in{'no'}) {
					$flag=1;
					$lx2 = $lx + 1;
					if (!$bot_res) {
						push(@new,"$count<>$in{'no'}<>$lx2<>$in{'sub'}<>$in{'email'}<>$in{'url'}<>$in{'name'}<>$date<>$in{'message'}<>$times<>$host<>$ango<>$in{'wrap'}<>$in{'oya'}<>$in{'smail'}<>0<>\n");
					}
				}
			}
			if ($bot_res && $flag != 2) {
				push(@new,"$count<>$in{'no'}<>$lx2<>$in{'sub'}<>$in{'email'}<>$in{'url'}<>$in{'name'}<>$date<>$in{'message'}<>$times<>$host<>$ango<>$in{'wrap'}<>$in{'oya'}<>$in{'smail'}<>0<>\n");
			}
			# 配列最終結合
			push(@new,@tmp);
		}
		## ツリーソート「なし」
		else {
			@new=();
			$flag=0;
			foreach (@lines) {
				chop;
				($no,$reno,$lx,$t,$e,$u,$n,$d,$m,$tm,$h,$a,$w,$OYA,$smail,$res) = split(/<>/);
				if ($bot_res && $flag == 1 && $lx2 > $lx && ($reno ne $in{'no'} || $OYA != $in{'oya'})) {
					$flag=2;
					push(@new,"$count<>$in{'no'}<>$lx2<>$in{'sub'}<>$in{'email'}<>$in{'url'}<>$in{'name'}<>$date<>$in{'message'}<>$times<>$host<>$ango<>$in{'wrap'}<>$in{'oya'}<>$in{'smail'}<>0<>\n");
				}

				# 直親記事
				if ($no == $in{'no'}) {
					$res++;
					push(@new,"$no<>$reno<>$lx<>$t<>$e<>$u<>$n<>$d<>$m<>$tm<>$h<>$a<>$w<>$OYA<>$smail<>$res<>\n");
				} else { push(@new,"$_\n"); }

				if ($no == $in{'no'}) {
					$flag=1;
       					$lx2 = $lx + 1;
					if (!$bot_res) {
       						push (@new,"$count<>$no<>$lx2<>$in{'sub'}<>$in{'email'}<>$in{'url'}<>$in{'name'}<>$date<>$in{'message'}<>$times<>$host<>$ango<>$in{'wrap'}<>$in{'oya'}<>$in{'smail'}<>0<>\n");
					}
				}
			}
			if ($bot_res && $flag != 2) {
				push(@new,"$count<>$in{'no'}<>$lx2<>$in{'sub'}<>$in{'email'}<>$in{'url'}<>$in{'name'}<>$date<>$in{'message'}<>$times<>$host<>$ango<>$in{'wrap'}<>$in{'oya'}<>$in{'smail'}<>0<>\n");
			}
	    	}
	}
	# 最大記事数処理
	@PAST=();
	if (@new > $max) {
		foreach (0 .. $#new) {
			# 最終尾ファイルを配列から抜き出し過去ログ配列へ
			local($p_file) = pop(@new);
			push(@PAST,$p_file);

			local($no,$reno,$lx) = split(/<>/, $p_file);
			if ($#new+1 <= $max && $reno eq 'no') {
				last;
			}
		}
	}
	# ログを更新
	unshift(@new,"$count\n");
	open(OUT,">$logfile") || &error("Write Error : $logfile");
	print OUT @new;
	close(OUT);

	# 過去ログ処理
	if ($pastkey) { &pastlog; }

	# ファイルロック解除
	&unlock if ($lockkey);

	# メール通知
	#if ($mailing == 2) { &mail_to; }
	#elsif ($mailing == 1 && $in{'email'} ne "$mailto") { &mail_to; }

	# 書きこみ後処理
	if ($in{'pview'} ne "on") { &after; }
	else { &list_view; }
}

#------------------------#
#  書きこみ後メッセージ  #
#------------------------#
sub after {
	if ($in{'url'}) { $in{'url'} = "http://$in{'url'}"; }

	# ツリートップ移動処理の場合は書き込み後はトップページ
	if ($top_sort) { $page = 0; }

	# 引用色
	if ($refcolor) {
		$in{'message'} =~ s/([\>]|^)(&gt;[^<]*)/$1<font color=\"$refcolor\">$2<\/font>/g;
	}

	# 図表モード
	if ($in{'wrap'} eq "pre") {
		$in{'message'} =~ s/<br>/\n/g;
		$in{'message'} = "<pre>$in{'message'}</pre>";
	}
	if ($in{'smail'} eq "on") { $in{'email'} = '非表示'; }

	&header;
	print <<"EOM";
<center>
<font color="$sub_color">
<BIG><b>正常に書きこみが完了しました</b></BIG></font>
<P><table border=1 cellpadding=10 width="90%">
<tr><td bgcolor="$tbl_color">
<TT>
おなまえ：<b>$in{'name'}</b><br>
Ｅメール：$in{'email'} $smail<br>
ＵＲＬ　：$in{'url'}<br>
タイトル：</TT><b>$in{'sub'}</b><br>
メッセージ<br><br>
<blockquote>
$in{'message'}
</blockquote>
</td></tr></table>
<P>
<form action="$script" method="$method">
<input type=hidden name=page value="$page">
<input type=submit value="リストにもどる">
</form>
</center>
</body>
</html>
EOM
	exit;
}

#--------------#
#  リスト表示  #
#--------------#
sub list_view {
	&header;
	print "<center>\n";

	if ($t_gif) {
		print "<img src=\"$t_gif\" alt=\"$title\" width=$t_wid height=$t_hgt>\n";
	} else {
		print "<font color=\"$t_color\" size=6 face=\"$t_face\"><B style=\"font-size:$t_point\">$title</B></font>\n";
	}

	print "<hr width='90%'>\n";
	print "[<a href=\"$home\" target='top'>もどる</a>]\n";
	print "[<a href=\"#msg\">新規投稿</a>]\n";

	if ($in{'list'} ne "new") {
		print "[<a href=\"$script?list=new\">新規順表\示</a>]\n";
	} else {
		print "[<a href=\"$script?list=tree\">ツリー表\示</a>]\n";
	}
	print "[<a href=\"$script?mode=new_sort&page=$page\">新着記事</a>]\n";
	print "[<a href=\"$script?mode=howto\">使い方</a>]\n";
	print "[<a href=\"$script?mode=find&page=$page&list=$in{'list'}\">ワード検索</a>]\n";
	if ($pastkey) { print "[<a href=\"$script?mode=past\">過去ログ</a>]\n"; }
#	print "[<a href=\"search/\">旧過去ログ</a>]\n";
	print "[<a href=\"$admin\">管理用</a>]\n";
	print "<hr width='90%'>\n";
	print "<table><tr><td nowrap><small>\n";
	print "<LI>$new_time時間以内の記事は <font color=\"$new_color\">$newmark</font> で表\示されます。<br>\n";
	if ($in{'list'} eq "new") {
		print "<LI>以下は新規投稿順のリスト表\示です。<br>\n";
	} else {
		print "<LI>ツリー先頭部の $treehead をクリックすると関連記事を一括表\示します。<br>\n";
	}
#	print "<LI><a href='./'>注意事項</a>を守っていない質問にはレスは致しません。<br>\n";
	print "</small></td></tr></table></center>\n";

	# ログを開く
	if ($in{'list'} eq "new") { &ListNewOpen; }
	else { &ListTreeOpen; }

	# ページ移動フォーム
	&move_list;

	# メッセージ投稿フォ−ムを表示
	&msg_form;

	# 著作権表示（削除しないで下さい）
	print "<P><center><small><!-- $ver -->\n";
	print "- <a href='http://www.kent-web.com/' target='_top'>Web Forum</a> -\n";
	print "</small></center>\n</body>\n</html>\n";
	exit;
}

#--------------------#
#  リストツリー表示  #
#--------------------#
sub ListTreeOpen {
	# 時間取得
	$times = time;

	# ページ区切り処理
	$x = 0;
	$start = $page + 1;
	$end   = $page + $p_tree;

	if ($mode ne "past") { print "<DL>\n"; }
	print "<UL>\n";

	open(IN,"$logfile") || &error("Open Error : $logfile");
	if ($mode ne "past") { $top = <IN>; }
	$i=0;
	while (<IN>) {
		local($no,$reno,$lx,$sub,$email,$url,$name,
			$dat,$msg,$timek,$h,$pw,$w,$oya,$smail,$res) = split(/<>/);

		if ($reno == 0) { $i++; }
		if ($i < $start) { next; }
		if ($i > $end) { next; }

		while ($x > $lx) { print "</UL>\n"; $x--; }
		while ($x < $lx) { print "<UL>\n"; $x++; }

		if ($reno == 0) { while ($x > 0) { print "</UL>\n"; $x--; } }

		# 所定時間以内の投稿は[NEWマーク]表示
		if (($times - $timek) > $new_time*3600) { $newsign = ""; }
		else { $newsign = "<font color=$new_color>$newmark</font>"; }

		# 記事タイトル長調整
		$sub = &cut_subject($sub);

		# 過去記事
		if ($mode eq "past") {
			print "<LI><a href=\"$script?mode=allread&pastlog=$in{'pastlog'}&no=$oya&page=$page&act=past\#$no\">$sub</a> - <b>$name</b> <SMALL>$dat <font color=$no_color>No\.$no</font> $newsign</SMALL>\n";
		# 削除記事
		} elsif ($pw eq 'DEL') {
			if ($lx == 0) {
#				print "<P><DT><a href=\"$script?mode=allread&no=$no&page=$page\">$treehead</a> - ";
				print "<DT><a href=\"$script?mode=allread&no=$no&page=$page\">$treehead</a> - ";
				print "$sub - <small>$dat <font color=$no_color>No\.$no</font></small>\n";
			} else {
				print "<LI>$sub - <small>$dat <font color=$no_color>No\.$no</font></small>\n";
			}
		# レス記事
		} elsif ($lx != 0) {
			print "<LI><a href=\"$script?no=$no&reno=$reno&oya=$oya&mode=msgview&page=$page\">$sub</a> - <b>$name</b> <SMALL>$dat <font color=$no_color>No\.$no</font> $newsign</SMALL>\n";

		# 親記事
		} else {
#			print "<P><DT><a href=\"$script?mode=allread&no=$no&page=$page\">$treehead</a> - ";
			print "<DT><a href=\"$script?mode=allread&no=$no&page=$page\">$treehead</a> - ";
			print "<a href=\"$script?no=$no&reno=$reno&oya=$oya&mode=msgview&page=$page\">$sub</a> - <b>$name</b> <SMALL>$dat <font color=$no_color>No\.$no</font> $newsign</SMALL>\n";
		}

	}
	close(IN);
	while ($x > 0) { print "</UL>\n"; $x--; }
	print "</UL>\n";
	if ($mode ne "past") { print "</DL>\n"; }
}

#--------------------#
#  リスト新着順表示  #
#--------------------#
sub ListNewOpen {
	# 時間取得
	$times = time;

	# ページ区切り処理
	$x = 0;
	$p_tree *= 3;
	$start = $page + 1;
	$end   = $page + $p_tree;

	open(IN,"$logfile") || &error("Open Error : $logfile");
	$top = <IN>;
	while (<IN>) {
		local($no,$reno,$xl,$sub,$email,$url,$name,$date,
			$msg,$time,$h,$pw,$wrap,$oya,$smail,$res) = split(/<>/);

		$count{$no} = $time;
		$re{$no}    = $reno;
		$d{$no}     = $date;
		$na{$no}    = $name;
		$no{$no}    = $no;
		$ttl{$no}   = $sub;
		$oya{$no}   = $oya;
		$time{$no}  = $time;
	}
	close(IN);

	print "<UL>\n";

	# ソート処理
	$i=0;
	foreach (sort { ($count{$b} <=> $count{$a}) || ($a cmp $b)} keys(%count)) {

		$i++;
		if ($i < $start) { next; }
		if ($i > $end) { next; }

		# 所定時間以内の投稿は[NEWマーク]表示
		if (($times - $time{$_}) > $new_time*3600) { $newsign = ""; }
		else { $newsign = "<font color=$new_color>$newmark</font>"; }

		if ($ttl{$_} eq '<s>投稿者削除</s>') {
			print "<LI>$ttl{$_} - <SMALL>$d{$_} <font color=$no_color>No\.$_</font> $newsign</SMALL>\n";
		} else {
			print "<LI><a href=\"$script?no=$_&reno=$re{$_}&oya=$oya{$_}&mode=msgview&list=new\">$ttl{$_}</a> - <b>$na{$_}</b> <SMALL>$d{$_} <font color=$no_color>No\.$_</font> $newsign</SMALL>\n";
		}
	}
	print "</UL>\n";
}

#------------------#
#  プレビュー画面  #
#------------------#
sub preview {
	&get_agent;

	if ($in{'name'} eq "" || $in{'message'} eq "")
		{ &error("名前又はメッセージに記入モレがあります"); }
	# E-Mail入力
	if ($in_email && $in{'email'} !~ /[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,3}/)
		{ &error("E-Mailの入力が不正です"); }
	# URL入力
#	if ($in{'no'} eq 'new' && !$in{'url'}) { &error("設置スクリプトのURL記述は必須です"); }
	# 題名入力
	if ($in{'sub'} eq "") { &error("「題名」の入力モレです"); }

	if ($in{'smail'} eq "on") { $smail = '(非表示)'; } else { $smail = ''; }

	&header;
	print <<"EOM";
<font color="$t_color"><big>
<b>- 以下の内容でメッセージを投稿します -</b></big></font>
<form action="$script" method="$method">
<input type=hidden name=mode value="regist">
<input type=hidden name=pwd value="$in{'pwd'}">
<input type=hidden name=name value="$in{'name'}">
<input type=hidden name=email value="$in{'email'}">
<input type=hidden name=url value="$in{'url'}">
<input type=hidden name=sub value="$in{'sub'}">
<input type=hidden name=wrap value="$in{'wrap'}">
<input type=hidden name=oya value="$in{'oya'}">
<input type=hidden name=pview value="$in{'pview'}">
<input type=hidden name=smail value="$in{'smail'}">
<input type=hidden name=page value="$page">
EOM
	if ($in{'action'} eq "res_msg") {
		print "<input type=hidden name=no value=\"$in{'no'}\">\n";
		print "<input type=hidden name=action value=\"res_msg\">\n";
		$width = $com_wid + 2;
	} else {
		print "<input type=hidden name=no value=\"new\">\n";
		$width = $com_wid;
	}
	$in{'message'} =~ s/<br>/\r/g;
	if ($in{'url'}) { $in{'url'} = "http://$in{'url'}"; }

	print <<"EOM";
<tt>
<b>投稿者名</b> ： <B>$in{'name'}</B><br>
<b>Ｅメール</b> ： $in{'email'} $smail<br>
<b>ＵＲＬ　</b> ： $in{'url'}<br>
<b>タイトル</b> ： <font color="$sub_color"><B>$in{'sub'}</B></font></tt>
<P><textarea cols="$width" rows=18 name=message wrap="soft">$in{'message'}</textarea>
<P><input type=submit value="メッセージを投稿する"></form>
<P>[<A HREF="javascript:history.back()">投稿フォームに戻る</A>]
</body>
</html>
EOM
	exit;
}

#----------------------#
#  メッセージ内容表示  #
#----------------------#
sub msgview {
	local($no,$reno,$lx,$sub,$email,$url,$name,
		$dat,$msg,$lt,$ho,$pw,$wrap,$oya,$smail,$res);

	$flag=0;
	@new=();
	open(IN,"$logfile") || &error("Open Error : $logfile");
	$top = <IN>;
	while (<IN>) {
		local($no,$reno,$lx,$sub,$email,$url,$name,
			$dat,$msg,$lt,$ho,$pw,$wrap,$oya,$smail,$res) = split(/<>/);

		if ($in{'oya'} == $oya) { push(@new,$_); }
		elsif ($flag && $in{'oya'} != $oya) { last; }
		if ($in{'no'} == $no) {
			$flag=1;
			$v_date  = $dat;
			$v_name  = $name;
			$v_email = $email;
			$v_url   = $url;
			$v_msg   = $msg;
			$v_time  = $lt;
			$v_sub   = $sub;
#			$v_oya   = $oya;
#			$v_no    = $no;
			$v_wrap  = $wrap;
			$v_smail = $smail;
		}
	}
	close(IN);

	if ($v_email) { $v_email = "<a href=\"mailto:$v_email\">$v_email</a>"; }
	if ($v_url) { $v_url = "<a href=\"http://$v_url\" target=\"_blank\">http://$v_url</a>"; }

	# レスメッセージ
	$res_msg = "\n\> $v_msg";
	$res_msg =~ s/&amp;/&/g;
#	$res_msg =~ s/&lt;/</g;
#	$res_msg =~ s/&gt;/>/g;
	$res_msg =~ s/<br>/\r> /g;

	# レスタイトル
	$res_sub = $v_sub;
	$res_sub =~ s/<([^>]|\n)*>//g;

	if ($res_sub =~ /^Re\^(\d+)\:(.*)/) {
		$renum = $1 + 1;
		$res_sub = "Re\^$renum\:$2";
	}
	elsif ($res_sub =~ /^Re\:(.*)/) { $res_sub = "Re\^2:$1"; }
	else { $res_sub = "Re: $res_sub"; }

	# HTMLを出力
	&header;
	print "<center>\n";

	if ($t_gif) {
		print "<img src=\"$t_gif\" alt=\"$title\" width=$t_wid height=$t_hgt>\n";
	} else {
		print "<font color=\"$t_color\" size=6 face=\"$t_face\"><b style=\"font-size:$t_point\">$title</b></font>\n";
	}

	print "<hr width='90%'>\n";
	print "[<a href=\"$script?page=$page&list=$in{'list'}\">記事リスト</a>]\n";
	print "[新規投稿]\n";
	print "[<a href=\"$script?mode=new_sort\">新着記事</a>]\n";
	print "[<a href=\"$script?mode=find\">ワード検索</a>]\n";
	if ($pastkey) { print "[<a href=\"$script?mode=past\">過去ログ</a>]\n"; }
	print "[<a href=\"$admin\">管理用</a>]\n";
	print "</center><hr width='90%'>\n";

	# 引用部色変更
	if ($refcolor) {
		$v_msg =~ s/([\>]|^)(&gt;[^<]*)/$1<font color=\"$refcolor\">$2<\/font>/g;
	}

	# 自動リンク
	if ($autolink) { &auto_link($v_msg); }

	# PREタグ
	if ($v_wrap eq 'pre') {
		$v_msg =~ s/<br>/\n/g;
		$v_msg = "<pre>$v_msg</pre>";
	}

	# 投稿日時
	$date = &get_time($v_time);

	print "<P><table cellspacing=0>\n";
	print "<tr><td><b>投稿日</b></td><td>： $date</td></tr>\n";
	print "<tr><td><b>投稿者</b></td><td>： <b>$v_name</b></td></tr>\n";
	if ($v_smail ne "on") {
		print "<tr><td><b>Ｅメール</b></td><td>： $v_email</td></tr>\n";
	}
	print "<tr><td><b>ＵＲＬ</b></td><td>： $v_url</td></tr>\n";
	print "<tr><td><b>タイトル</b></td><td>： <b><font color=$sub_color>$v_sub</font></b></td></tr></table>\n";
	print "<blockquote>$v_msg</blockquote><P>\n";

	if (@new > 1) {
	print "<hr width='95%'><b style='text-indent:18'>- 関連一覧ツリー</b>\n";
	print "（$treehead をクリックするとツリー全体を一括表\示します）<br>\n";

	$x = 0;
	print "<UL>\n";
	foreach (@new) {
		local($no,$reno,$lx,$sub,$email,$url,$name,
			$dat,$msg,$lt,$ho,$p,$w,$oya,$smail,$res) = split(/<>/);

		while ($x > $lx) { print "</UL>\n"; $x--; }
		while ($x < $lx) { print "<UL>\n"; $x++; }

		# 記事タイトル長調整
		$sub = &cut_subject($sub);

		if ($lx != 0) {
			print "<LI><a href=\"$script?no=$no&reno=$reno&oya=$oya&mode=msgview\">$sub</a> - <B>$name</B> $dat ";

		} else {
			print "<a href=\"$script?mode=allread&no=$no&page=$page\">$treehead</a> - ";
			print "<a href=\"$script?no=$no&reno=$reno&oya=$oya&mode=msgview\">$sub</a> - <B>$name</B> $dat";
		}

		if ($in{'no'} == $no) {
			print "<font color=$sub_color><B>No\.$no</B></font>\n";
		} else {
			print "<font color=$no_color>No\.$no</font>\n";
		}
	}
	while ($x > 0) { print "</UL>\n"; $x--; }
	print "</UL>\n";
	}

	# 返信フォーム
	&msg_form;

	# 著作権表示（削除しないで下さい）
	print "<P><center><small><!-- $ver -->\n";
	print "- <a href='http://www.kent-web.com/' target='_top'>Web Forum</a> -\n";
	print "</small></center>\n</body>\n</html>\n";
	exit;
}

#----------------#
#  一括表示機能  #
#----------------#
sub allread {
	# HTMLを出力
	&header;
	print "[<a href=\"$script?page=$page&mode=$in{'act'}\">リストへもどる</a>]<br>\n";
	print "<table width='100%'><tr><th bgcolor=\"#004080\">\n";
	print "<font color=\"#FFFFFF\">一括表\示</font></th></tr></table>\n";

	# 過去ログの場合
	if ($in{'act'} eq "past") {
		# ログファイルを定義
		if ($in{'pastlog'}) {
			$count = $in{'pastlog'};
		} else {
			open(NO,"$nofile") || &error("Open Error : $nofile");
			$count = <NO>;
			close(NO);
		}
		$count = sprintf("%04d", $count);
		$logfile = "$pastdir$count\.cgi";
	}

	# 親記事を出力
	$x = 0;
	print "<UL>\n";

	open(IN,"$logfile") || &error("Open Error : $logfile");
	$top = <IN> if ($in{'act'} ne "past");
	$flag=0;
	while (<IN>) {
		($no,$reno,$lx,$sub,$email,$url,$name,
			$dat,$msg,$t,$h,$pw,$wrap,$oya) = split(/<>/);

		if ($in{'no'} eq "$oya") {
			$flag=1;
			push(@new,$_);

			while ($x > $lx) { print "</UL>\n"; $x--; }
			while ($x < $lx) { print "<UL>\n"; $x++; }

			# 記事タイトル長調整
			$sub = &cut_subject($sub);

			if ($pw eq 'DEL') {
				print "<LI>$sub - $dat <font color=\"$no_color\">No\.$no</font>\n";
			} else {
				print "<LI><a href=\"#$no\">$sub</a> - <B>$name</B> $dat";
				print " <font color=\"$no_color\">No\.$no</font>\n";
			}
		}
		elsif ($flag && $in{'no'} != $oya) { last; }
	}
	close(IN);
	while ($x > 0) { print "</UL>\n"; $x--; }
	print "</UL>\n<hr><center>\n";

	foreach (@new) {
		($no,$reno,$lx,$sub,$email,$url,$name,
			$dat,$msg,$t,$ho,$pw,$wrap,$oya,$smail,$res) = split(/<>/);

		if ($pw eq 'DEL') { next; }

		# 自動リンク
		if ($autolink) { &auto_link($msg); }

		if ($url) { $url="<a href=\"http://$url\" target='_top'>http://$url</a>"; }
		if ($email) { $email="<a href=\"mailto:$email\">$email</a>"; }

		# 引用部色変更
		if ($refcolor) {
			$msg =~ s/([\>]|^)(&gt;[^<]*)/$1<font color=\"$refcolor\">$2<\/font>/g;
		}

		# 図表モード
		if ($wrap eq 'pre') {
			$msg =~ s/<br>/\n/g;
			$msg = "<pre>$msg</pre>";
		}

		$date = &get_time($t);

		print "<a name=\"$no\"></a>\n";
		print "<table border=1 width='95%' cellpadding=5>\n";
		print "<tr><td bgcolor=$tbl_color><TT>\n";
		print "投稿時間：$date<br>投稿者名：<b>$name</b><br>\n";
		if ($smail ne "on") { print "Ｅメール：$email<br>\n"; }
		print "ＵＲＬ　：$url<br>\n";
		print "タイトル：</TT><font color=$sub_color><b>$sub</b></font><br>\n";
		print "<blockquote>$msg</blockquote>\n";
		if ($in{'act'} ne "past") {
			print "<div align=right>\n";
			print "<form action=\"$script\#msg\" method=\"$method\">\n";
			print "<input type=hidden name=mode value=msgview>\n";
			print "<input type=hidden name=reno value=$reno>\n";
			print "<input type=hidden name=no value=$no>\n";
			print "<input type=hidden name=oya value=$oya>\n";
			print "<input type=hidden name=page value=\"$page\">\n";
			print "<input type=submit value=\"返信する\"></form></div>\n";
		}
		print "</td></tr></table><br>\n";
	}
	print "</center>\n</body>\n</html>\n";
	exit;
}

#----------------------------#
#  記事を新着順にソート表示  #
#----------------------------#
sub new_sort { 
	&header;
	print "[<a href=\"$script?page=$page\">リストへもどる</a>]\n";
	print "<table width='100%'><tr><th bgcolor=\"#004080\">\n";
	print "<font color=\"#FFFFFF\">新着記事</font></th></tr></table>\n";
	print "<br><center>\n";
	print "<font color=$sub_color><b>- 新着記事$sortcnt件を表\示しました -</b></font><P>\n";

	open(IN,"$logfile") || &error("Open Error : $logfile");
	$top = <IN>;
	while (<IN>) {
		($no,$reno,$x,$sub,$email,$url,$name,$date,
			$msg,$time,$h,$pw,$wrap,$oya,$smail,$res) = split(/<>/);

		if ($pw eq 'DEL') { next; }

		# 自動リンク
		if ($autolink) { &auto_link($msg); }

		$count{$no} = $time;
#		$d{$no}     = $date;
		$na{$no}    = $name;
		$em{$no}    = $email;
		$url{$no}   = $url;
		$no{$no}    = $no;
		$reno{$no}  = $reno;
		$ttl{$no}   = $sub;
		$oya{$no}   = $oya;
		$msg{$no}   = $msg;
		$wrap{$no}  = $wrap;
		$smail{$no} = $smail;
	}
	close(IN);

	# ソート処理
	$i=0;
	foreach (sort { ($count{$b} <=> $count{$a}) || ($a cmp $b)} keys(%count)) {
		$i++;
		if ($i > $sortcnt) { last; } # ループを抜ける

		# 新着記事を出力
		if ($em{$_}) { $em{$_} = "<a href=mailto:$em{$_}>$em{$_}</a>"; }
		if ($url{$_}) {
			$url{$_} = "<a href=\"http://$url{$_}\" target='_top'>http://$url{$_}</a>";
		}

		# 引用部色変更
		if ($refcolor) {
			$msg{$_} =~ s/([\>]|^)(&gt;[^<]*)/$1<font color=\"$refcolor\">$2<\/font>/g;
		}

		# PRE機能
		if ($wrap{$_} eq "pre") {
			$msg{$_} =~ s/<br>/\n/g;
			$msg{$_} = "<pre>$msg{$_}</pre>";
		}

		$date = &get_time($count{$_});

		print "<table border=1 width='95%' cellpadding=5>\n";
		print "<tr><td bgcolor=$tbl_color><TT>\n";
		print "投稿時間：$date<br>投稿者名：<b>$na{$_}</b><br>\n";
		if ($smail{$_} ne "on") { print "Ｅメール：$em{$_}<br>\n"; }
		print "ＵＲＬ　：$url{$_}<br>\n";
		print "タイトル：<font color=$sub_color><b>$ttl{$_}</b></font></TT>\n";
		print "<blockquote>$msg{$_}</blockquote>\n";
		print "<div align=right>\n";
		print "<form action=\"$script\#msg\" method=\"$method\">\n";
		print "<input type=hidden name=mode value=msgview>\n";
		print "<input type=hidden name=reno value=$reno{$_}>\n";
		print "<input type=hidden name=no value=$no{$_}>\n";
		print "<input type=hidden name=oya value=$oya{$_}>\n";
		print "<input type=hidden name=page value=\"$page\">\n";
		print "<input type=submit value=\"返信する\"></form></div>\n";
		print "</td></tr></table><br>\n";
	}
	print "</center>\n</body>\n</html>\n";
	exit;
}

#------------------#
#  HTMLのヘッダー  #
#------------------#
sub header {
	print "Content-type: text/html\n\n";
	$head_flag = 1;
	print <<"EOM";
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=Shift_JIS">
<META HTTP-EQUIV="Content-Style-Type" content="text/css">
<STYLE type="text/css">
<!--
body,tr,td,th { font-size: $pt; font-family: "$t_face"; }
a:hover       { text-decoration: underline; color: $alink; }
big           { font-size: 12pt; }
small         { font-size: 9pt; }
-->
</STYLE>
<title>$title</title></head>
$body
EOM
}

#--------------#
#  エラー処理  #
#--------------#
sub error {
	&unlock if ($lockflag);

	&header if (!$head_flag);
	print "<center><hr width=400><h3>ERROR !</h3>\n";
	print "<font color='#CC0000'>$_[0]</font>\n";
	print "<P><hr width=400></center>\n</body>\n</html>\n";
	exit;
}

#------------------#
#  投稿フォーム部  #
#------------------#
sub msg_form {
	&get_cookie;
	&get_agent;

	print "<hr width='95%'><a name=\"msg\"></a>\n";

	if ($mode eq 'msgview') {
		$width = $com_wid + 2;
		print "<b style='text-indent:18'>- 返信フォーム</b>\n";
		print "（この記事に返信する場合は下記フォームから投稿して下さい）<br>\n";
		print "<form action=\"$script\" method=\"$method\">\n";
		print "<input type=hidden name=page value=\"$page\">\n";
		print "<input type=hidden name=action value=\"res_msg\">\n";
		print "<input type=hidden name=no value=\"$in{'no'}\">\n";
		print "<input type=hidden name=oya value=\"$in{'oya'}\">\n";
	} else {
		$width = $com_wid;
		print "<center><b><big>メッセージをどうぞ・・</big></b></a>\n";
#		print "<P><font color=\"$sub_color\">- 必ずスクリプトの設置URLを記述して下さい -</font><br>\n";
		print "</center>\n";
		print "<form action=\"$script\" method=\"$method\">\n";
		print "<input type=hidden name=page value=\"$page\">\n";
		print "<input type=hidden name=no value=\"new\">\n";
	}

	# 匿メール／プレビューのチェック
	if ($c_smail eq "on") { $checked1 = "checked"; }
	if ($c_pview eq "on") { $checked2 = "checked"; }

	print <<"EOM";
<input type=hidden name=mode value="form">
<blockquote>
<table border=0 cellspacing=0 cellpadding=1>
<tr>
  <td nowrap><b>おなまえ</b></td>
  <td><input type=text name=name size="$nam_wid" value="$c_name"></td>
</tr>
<tr>
  <td nowrap><b>Ｅメール</b></td>
  <td>
    <input type=text name=email size="$nam_wid" value="$c_email">
    <input type=checkbox name=smail value="on" $checked1><a href="$script?mode=howto&view=hihyouji"><small>非表\示</small></a>
  </td>
</tr>
<tr>
  <td nowrap><b>タイトル</b></td>
  <td>
    <input type=text name=sub size="$sub_wid" value="$res_sub"> 
    <INPUT TYPE=submit VALUE="投稿する"><INPUT TYPE=reset VALUE="リセット">
  </td>
</tr>
<tr>
  <td colspan=2>
    <b>メッセージ</b>&nbsp;&nbsp;&nbsp;
    <input type=radio name=wrap value="soft" checked>手動改行
    <input type=radio name=wrap value="hard">強制改行
    <input type=radio name=wrap value="pre">図表\モード<BR>
    <textarea name=message rows=10 cols="$width" wrap="soft">$res_msg</textarea>
  </td>
</tr>
<tr>
  <td nowrap><b>ＵＲＬ</b></td>
  <td><input type=text name="url" size="$url_wid" value="http://$c_url"></td>
</tr>
<tr>
  <td nowrap><b>パスワード</b></td>
  <td>
    <input type=password name=pwd size=8 value="$c_pwd" maxlength=8>
    <small>(英数字で8文字以内)</small>
  </td>
</tr>
<tr>
  <td nowrap><b>プレビュー</b></td>
  <td><input type=checkbox name=pview value="on" $checked2></td>
</tr>
</table>
</form></blockquote>
<hr width='95%'>
<center><form acion="$script" method="$method">
<input type=hidden name=page value="$page">
<font color="$sub_color"><small>
- 以下のフォームから自分の投稿記事を修正・削除することができます -</font><br>
処理 <select name=mode>
<option value="usr_edt">修正
<option value="usr_del">削除
</select>
記事No <input type=text name=no size=4>
パスワード <input type=password name=pwd size=6></small>
<input type=submit value="送信">
</form><hr width='95%'></center>
EOM
}

#----------------#
#  記事修正処理  #
#----------------#
sub usr_edt {
	# POST限定
	if ($MethPost && !$post_flag) { &error("不正なアクセスです"); }

	# フォーム内容のチェック
	if ($in{'no'} eq '' || $in{'pwd'} eq '')
		{ &error("記事NOまたはパスワードの記入モレがあります"); }

	if ($in{'action'} eq "edit") {
		# フォームチェック
		if ($in{'name'} eq "" || $in{'message'} eq "")
			{ &error("名前又はメッセージに記入モレがあります"); }
		if ($in_email && $in{'email'} !~ /(.+)\@(.+)\.(.+)/)
			{ &error("E-Mailの入力が不正です"); }
		# URL入力
		if ($in{'no'} eq 'new' && !$in{'url'})
			{ &error("設置スクリプトのＵＲＬ記述は必須です"); }
		# 題名入力
		if ($in{'sub'} eq "") { &error("「題名」の入力モレです"); }

		# ロック処理
		&lock if ($lockkey);
	}

	$flag=0;
	open(IN,"$logfile") || &error("Open Error : $logfile");
	$top = <IN>;
	while (<IN>) {
		chop;
		($no,$reno,$lx,$sub,$email,$url,$name,$dat,
			$msg,$lt,$ho,$pw,$wrap,$oya,$smail,$res) = split(/<>/);

		if ($in{'no'} == $no) {
			$pw2 = $pw;
			$sm2 = $smail;
			$flag=1;
			if ($in{'action'} ne "edit") { last; }
			else { $_ = "$no<>$reno<>$lx<>$in{'sub'}<>$in{'email'}<>$in{'url'}<>$in{'name'}<>$dat<>$in{'message'}<>$lt<>$ho<>$pw<>$in{'wrap'}<>$oya<>$in{'smail'}<>$res<>"; }
		}
		if ($in{'action'} eq "edit") { push(@new,"$_\n"); }
	}
	close(IN);
	if (!$flag) { &error("該当の記事が見当たりません"); }
	if ($pw2 eq "") { &error("パスワードが設定されていません"); }
	$check = &decrypt("$in{'pwd'}", "$pw2");
	if ($check ne "yes") { &error("パスワードが違います"); }

	@wrap1 = ('手動改行', '強制改行', '図表モード');
	@wrap2 = ('soft', 'hard', 'pre');

	if ($in{'action'} eq "edit") {
		unshift(@new,$top);
		open(OUT,">$logfile") || &error("Write Error : $logfile");
		print OUT @new;
		close(OUT);

		&unlock if ($lockkey);

		if ($in{'url'}) { $in{'url'} = "http://$in{'url'}"; }
		if ($in{'wrap'} eq "pre") { $in{'message'} = "<pre>$in{'message'}</pre>"; }
		if ($refcolor) {
			$in{'message'} =~ s/([\>]|^)(&gt;[^<]*)/$1<font color=\"$refcolor\">$2<\/font>/g;
		}
		foreach (0 .. 2) {
			if ($wrap2[$_] eq "$in{'wrap'}") { $wp=$_; last; }
		}
		if ($in{'smail'} eq "on") { $in{'email'} = '非表示'; }

		&header;
		print "<blockquote>\n";
		print "<b>- 以下のとおり修正が完了しました -</b>\n";
		print "<P><tt>\n";
		print "お名前：$in{'name'}<br>\n";
		print "メール：$in{'email'}<br>\n";
		print "題　名：$in{'sub'}<br>\n";
		print "ＵＲＬ：$in{'url'}<br>\n";
		print "改　行：$wrap1[$wp]<br>\n";
		print "本　文：</tt><P>\n";
		print "$in{'message'}\n";
		print "<P><form action=\"$script\">\n";
		print "<input type=submit value='リストに戻る'></form>\n";
		print "</blockquote>\n</body>\n</html>\n";
		exit;
	}

	&get_agent;
	$msg =~ s/<br>/\r/g;
	$msg =~ s/&lt;/</g;
	$msg =~ s/&gt;/>/g;
	$msg =~ s/&amp;/&/g;

	if ($sm2 eq "on") { $sm2 = "checked"; }

	&header;
	print <<"EOM";
<center>
<b>- 変更する部分のみ修正して送信ボタンを押して下さい -</b>
<P>
<form action="$script" method="$method">
<input type=hidden name=mode value="usr_edt">
<input type=hidden name=action value="edit">
<input type=hidden name=pwd value="$in{'pwd'}">
<input type=hidden name=no value="$in{'no'}">
<table border=0 cellspacing=0 cellpadding=1>
<tr>
  <td nowrap><b>おなまえ</b></td>
  <td><input type=text name=name size="$nam_wid" value="$name"></td>
</tr>
<tr>
  <td nowrap><b>Ｅメール</b></td>
  <td>
    <input type=text name=email size="$nam_wid" value="$email">
    <input type=checkbox name=smail value="on" $sm2>非表\示
  </td>
</tr>
<tr>
  <td nowrap><b>タイトル</b></td>
  <td>
    <input type=text name=sub size="$sub_wid" value="$sub"> 
    <INPUT TYPE=submit VALUE="送信する"><INPUT TYPE=reset VALUE="リセット">
  </td>
</tr>
<tr>
  <td colspan=2>
    <b>メッセージ</b>&nbsp;&nbsp;&nbsp;
EOM

	foreach (0 .. 2) {
		if ($wrap eq "$wrap2[$_]") {
			print "<input type=radio name=wrap value=\"$wrap2[$_]\" checked>$wrap1[$_]\n";
		} else {
			print "<input type=radio name=wrap value=\"$wrap2[$_]\">$wrap1[$_]\n";
		}
	}

	print <<"EOM";
<BR>
    <textarea name=message rows=14 cols="$com_wid" wrap="soft">$msg</textarea>
  </td>
</tr>
<tr>
  <td nowrap><b>ＵＲＬ</b></td>
  <td><input type=text name="url" size="$url_wid" value="http://$url"></td>
</tr></table></form></center>
</body>
</html>
EOM
	exit;
}

#----------------#
#  記事削除処理  #
#----------------#
sub usr_del {
	# POST限定
	if ($MethPost && !$post_flag) { &error("不正なアクセスです"); }

	# フォーム内容のチェック
	if ($in{'no'} eq '' || $in{'pwd'} eq '')
		{ &error("記事NOまたはパスワードの記入モレがあります"); }

	# 確認画面
	if ($in{'keyno'} eq "") {
		$flag=0;
		open(IN,"$logfile") || &error("Open Error : $logfile");
		$top = <IN>;
		while (<IN>) {
			($no,$reno,$lx,$tl,$em,$ur,$na,$dt,$msg,$tm,$ho,$ango,$wrap,$oya,$smail,$res) = split(/<>/);
			if ($in{'no'} == $no) { $flag=1; last; }
		}
		close(IN);
		if (!$flag) { &error("該当の記事は見当たりません"); }
		if ($ango eq "") { &error("この記事（No $in{'no'}）は削除キーが設定されていません"); }
		# 照合
		$match = &decrypt("$in{'pwd'}", "$ango");
		if ($match ne "yes") { &error("削除キーが違います"); }

		# 引用部色変更
		if ($refcolor) {
			$msg =~ s/([\>]|^)(&gt;[^<]*)/$1<font color=\"$refcolor\">$2<\/font>/g;
		}
		if ($ur) { $ur = "http://$ur"; }
		$date = &get_time($tm);
		&header;
		print "<center><h3>以下の記事を本当に削除しますか？</h3>\n";
		print "<table border=1 bgcolor=\"$tbl_color\" cellpadding=10 width='80%'><tr><td><tt>\n";
		print "記事番号：<b>$no</b><br>\n";
		print "投稿日時：$date<br>\n";
		print "投稿者名：<b>$na</b><br>\n";
		print "Ｅメール：$em<br>\n" if ($smail ne "on");
		print "ＵＲＬ　：$ur<br>\n";
		print "タイトル：<font color=\"$sub_color\"><b>$tl</b></font><br>\n";
		print "</tt><P>$msg\n";
		print "</td></tr></table>\n";
		print "<P><table><tr><td>\n";
		print "<form action=\"$script\" method=$method>\n";
		print "<input type=hidden name=mode value=usr_del>\n";
		print "<input type=hidden name=no value=\"$in{'no'}\">\n";
		print "<input type=hidden name=pwd value=\"$in{'pwd'}\">\n";
		print "<input type=hidden name=keyno value=\"$reno\">\n";
		print "<input type=submit value='本当に削除する'></td></form>\n";
		print "<td width=15></td><td><form><input type=button value='キャンセルする' onClick=\"history.back()\"></td></form>\n";
		print "</tr></table>\n</center>\n</body>\n</html>\n";
		exit;
	}

	# ロック開始
	&lock if ($lockkey);

	# ログを読み込む
	$new=();
	$flag=0;
	open(IN,"$logfile") || &error("Open Error : $logfile");
	$top = <IN>;
	while (<IN>) {
		chop;
		($no,$reno,$lx,$tl,$em,$ur,$na,$dt,$msg,
			$tm,$ho,$ango,$w,$oya,$smail,$res) = split(/<>/);

		if ($in{'no'} == $no) {
			if ($ango eq "") { $flag=2; last; }
			$match = &decrypt("$in{'pwd'}", "$ango");
			if ($match ne "yes") { $flag=3; last; }
			else { $flag=1; }

			if (!$res) { next; }
			$_ = "$no<>$reno<>$lx<><s>投稿者削除</s><><><>(削除)<>$dt<>(投稿者により削除されました)<>$tm<>$ho<>DEL<>$w<>$oya<>$smail<>$res<>";
		} elsif ($no == $in{'keyno'}) {
			if ($res > 0) { $res--; }
			$_ = "$no<>$reno<>$lx<>$tl<>$em<>$ur<>$na<>$dt<>$msg<>$tm<>$ho<>$ango<>$w<>$oya<>$smail<>$res<>";
		}
		push(@new,"$_\n");
	}
	close(IN);

	if ($flag == 0) { &error("該当記事は見つかりません"); }
	elsif ($flag == 2) { &error("パスワードが設定されていません"); }
	elsif ($flag == 3) { &error("パスワードが違います"); }

	# ログを更新
	unshift(@new,$top);
	open(OUT,">$logfile") || &error("Write Error : $logfile");
	print OUT @new;
	close(OUT);

	# ロック解除
	&unlock if ($lockkey);

	# リスト表示部にもどる
	&list_view;
}

#----------------------#
#  投稿フォームを調整  #
#----------------------#
sub get_agent {
	# ブラウザ情報を取得
	$agent = $ENV{'HTTP_USER_AGENT'};

	if ($agent =~ /MSIE 3/i) {
		$nam_wid = 30;
		$sub_wid = 40;
		$com_wid = 64;
		$url_wid = 46;
	} elsif ($agent =~ /MSIE 4/i || $agent =~ /MSIE 5/i) {
		$nam_wid = 30;
		$sub_wid = 40;
		$com_wid = 64;
		$url_wid = 70;
	} else {
		$nam_wid = 20;
		$sub_wid = 27;
		$com_wid = 62;
		$url_wid = 52;
	}
}

#--------------#
#  ロック処理  #
#--------------#
sub lock {
	local($retry) = 5;
	if (-e $lockfile) {
		local($mtime) = (stat($lockfile))[9];
		if ($mtime < time - 60) { &unlock; }
	}
	# symlink関数式ロック
	if ($lockkey == 1) {
		while (!symlink(".", $lockfile)) {
			if (--$retry <= 0) { &error('LOCK is BUSY'); }
			sleep(1);
		}
	# mkdir関数式ロック
	} elsif ($lockkey == 2) {
		while (!mkdir($lockfile, 0755)) {
			if (--$retry <= 0) { &error('LOCK is BUSY'); }
			sleep(1);
		}
	}
	$lockflag=1;
}

#--------------#
#  ロック解除  #
#--------------#
sub unlock {
	if ($lockkey == 1) { unlink($lockfile); }
	elsif ($lockkey == 2) { rmdir($lockfile); }
	$lockflag=0;
}

#--------------#
#  メール送信  #
#--------------#
sub mail_to {
	# メールタイトル
	$MailSub = "[wforum0:$count] $in{'sub'}";

	# メール本文のタグ・改行を復元
	$message = $in{'message'};
	$message =~ s/&lt;/</g;
	$message =~ s/&gt;/>/g;
	$message =~ s/&amp;/&/g;
	$message =~ s/<br>/\n/g;

	if ($in{'url'}) { $in{'url'} = "http://$in{'url'}"; }
	$date2 = &get_time($times);

	# メール本文
	$MailBody = <<"EOM";
------------------------------------------------------------
投稿時間：$date2
ホスト名：$host
ブラウザ：$ENV{'HTTP_USER_AGENT'}

投稿者名：$in{'name'}
Ｅメール：$in{'email'}
タイトル：$in{'sub'}
ＵＲＬ  ：$in{'url'}
コメント：

$message
------------------------------------------------------------
EOM

	&jcode'convert(*MailSub,'jis');
	&jcode'convert(*MailBody,'jis');

	if ($in{'email'} eq "") { $in{'email'} = 'nomail@xxx.xxx'; }

	open(MAIL,"| $sendmail -t") || &error("メール送信に失敗しました");
	print MAIL "To: $mailto\n";
	print MAIL "From: $in{'email'}\n";
	print MAIL "Subject: $MailSub\n";
	print MAIL "MIME-Version: 1.0\n";
	print MAIL "Content-type: text/plain; charset=ISO-2022-JP\n";
	print MAIL "Content-Transfer-Encoding: 7bit\n";
	print MAIL "X-Mailer: $ver\n\n";
	print MAIL "$MailBody\n";
	close(MAIL);
}

#------------------#
#  クッキーの発行  #
#------------------#
sub set_cookie {
	local(@mon,@week,$gmt,$cook);
	local($sec,$min,$hour,$mday,$mon,$year,$wday) = gmtime(time + 60*24*60*60);
	@mon  = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	@week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');

	$gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT",
			$week[$wday],$mday,$mon[$mon],$year+1900,$hour,$min,$sec);
	$cook="name<>$in{'name'}<>email<>$in{'email'}<>url<>$in{'url'}<>pwd<>$in{'pwd'}<>pview<>$in{'pview'}<>smail<>$in{'smail'}";
	print "Set-Cookie: WEB_FORUM=$cook; expires=$gmt\n";
}

#------------------#
#  クッキーを取得  #
#------------------#
sub get_cookie {
	local($key, $val, @cook, %tmp);
	@cook = split(/;/, $ENV{'HTTP_COOKIE'});
	foreach (@cook) {
		($key, $val) = split(/=/);
		$key =~ s/\s//g;
		$tmp{$key} = $val;
	}
	%ck = split(/<>/, $tmp{'WEB_FORUM'});
	$c_name  = $ck{'name'};
	$c_email = $ck{'email'};
	$c_url   = $ck{'url'};
	$c_pwd   = $ck{'pwd'};
	$c_pview = $ck{'pview'};
	$c_smail = $ck{'smail'};
}

#----------------------#
#  パスワード暗号処理  #
#----------------------#
sub encrypt {
	local($inpw) = $_[0];
	local(@SALT, $salt, $encrypt);

	@SALT = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/');
	srand;
	$salt = $SALT[int(rand(@SALT))] . $SALT[int(rand(@SALT))];
	$encrypt = crypt($inpw, $salt) || crypt ($inpw, '$1$' . $salt);
	return $encrypt;
}

#----------------------#
#  パスワード照合処理  #
#----------------------#
sub decrypt {
	local($inpw, $logpw) = @_;
	local($salt, $key, $check);

	$salt = $logpw =~ /^\$1\$(.*)\$/ && $1 || substr($logpw, 0, 2);
	$check = "no";
	if (crypt($inpw, $salt) eq "$logpw" || crypt($inpw, '$1$' . $salt) eq "$logpw")
		{ $check = "yes"; }
	return $check;
}

#----------------#
#  検索フォーム  #
#----------------#
sub find {
	&header;
	print <<"EOM";
[<a href="$script?page=$page&list=$in{'list'}">リストに戻る</a>]
<table width="100%"><tr><th bgcolor="#004080">
  <font color="#FFFFFF">キーワード検索</font>
</th></tr></table>
<P><a name="SEARCH"></a>
<UL>
<LI>検索したい<b>キーワード</b>を入力し、検索条件を選択して「検索する」を押してください。
<LI>複数のキーワードを入力するときは、<b>半角スペース</b>で区切って下さい。
<form action="$script" method="$method">
<input type=hidden name=mode value="find">
<input type=hidden name=list value="$in{'list'}">
キーワード：<input type=text name=word size=30 value="$in{'word'}">
検索条件：<select name="cond">
EOM
	foreach ('AND', 'OR') {
		if ($in{'cond'} eq "$_") {
			print "<option value=\"$_\" selected>$_\n";
		} else {
			print "<option value=\"$_\">$_\n";
		}
	}
	print "</select>\n";
	if ($in{'view'} eq "") { $in{'view'} = $p_tree; }
	print "表\示件数：<select name=view>\n";
	foreach (5,10,15,20,25,30) {
		if ($in{'view'} eq "$_") {
			print "<option value=\"$_\" selected>$_件\n";
		} else {
			print "<option value=\"$_\">$_件\n";
		}
	}
	print "</select>\n";
	print "<input type=submit value=\" 検索 \"></form>\n</UL>\n";

	# ワード検索の実行と結果表示
	if ($in{'word'} ne "") { &search; }

	print "</body>\n</html>\n";
	exit;
}

#----------------#
#  検索処理実行  #
#----------------#
sub search {
	# 入力内容を整理
	$in{'word'} =~ s/　/ /g;
	@pairs = split(/\s+/, $in{'word'});

	# ロック処理：サーバ負荷を考慮し多重起動回避のため
	&lock if ($lockkey);

	# ファイルを読み込み
	@new=();
	open(IN,"$logfile") || &error("Open Error : $logfile");
	$top = <IN> if ($mode ne "past");
	while (<IN>) {
		$flag=0;
		foreach $pair (@pairs) {
			if (index($_,$pair) >= 0) {
				$flag=1;
				if ($in{'cond'} eq 'OR') { last; }
			} else {
				if ($in{'cond'} eq 'AND') { $flag=0; last; }
			}
		}
		if ($flag) { push(@new,$_); }
	}
	close(IN);

	# 検索終了
	$count = @new;
	print "検索結果：<b>$count</b>件\n";
	if ($in{'page'} eq '') { $in{'page'} = 0; }
	$end_data = @new - 1;
	$page_end = $in{'page'} + $in{'view'} - 1;
	if ($page_end >= $end_data) { $page_end = $end_data; }

	$enwd = &url_enc($in{'word'});

	$next_line = $page_end + 1;
	$back_line = $in{'page'} - $in{'view'};

	if ($back_line >= 0) {
		print "[<a href=\"$script?mode=$mode&page=$back_line&word=$enwd&view=$in{'view'}&cond=$in{'cond'}&pastlog=$in{'pastlog'}\">前の$in{'view'}件</a>]\n";
	}
	if ($page_end ne "$end_data") {
		print "[<a href=\"$script?mode=$mode&page=$next_line&word=$enwd&view=$in{'view'}&cond=$in{'cond'}&pastlog=$in{'pastlog'}\">次の$in{'view'}件</a>]\n";
	}

	# ヒットした記事を表示
	print "<hr>\n";
	foreach ($in{'page'} .. $page_end) {
		($no,$reno,$lx,$sub,$em,$ur,$na,$dt,
			$msg,$tm,$ho,$ango,$w,$oya,$smail) = split(/<>/, $new[$_]);

		if ($em) { $em = "<a href=\"mailto:$em\">$em</a>"; }
		if ($ur) { $ur = "<a href=\"http://$ur\" target=\"_blank\">http://$ur</a>"; }
		if ($w eq "pre") {
			$msg =~ s/<br>/\r/g;
			$msg = "<pre>$msg</pre>";
		}
		if ($autolink) { &auto_link($msg); }
		if ($refcolor) {
			$msg =~ s/([\>]|^)(&gt;[^<]*)/$1<font color=\"$refcolor\">$2<\/font>/g;
		}
		$date = &get_time($tm);
		print "<table cellspacing=0 cellpadding=1>\n";
		print "<tr><td>記事No<td>： <b>$no</b> &nbsp;&nbsp;";
		if ($in{'pastlog'}) {
			print "[<a href=\"$script?mode=allread&no=$oya&pastlog=$in{'pastlog'}&act=past\">関連記事</a>]</tr>\n";
		} else {
			print "[<a href=\"$script?mode=allread&no=$oya\">関連記事</a>]</tr>\n";
		}
		print "<tr><td>投稿日<td>： $date</tr>\n";
		print "<tr><td>投稿者<td>： <b>$na</b></tr>\n";
		print "<tr><td>E-Mail<td>： $em</tr>\n" if ($smail ne "on");
		print "<tr><td>ＵＲＬ<td>： $ur</tr>\n" if ($ur);
		print "<tr><td>題　名<td>： <font color=$sub_color><b>$sub</b></font></tr></table>\n";
		print "<blockquote>$msg</blockquote><hr>\n";
	}
	if ($count) {
		print "<a href=\"#SEARCH\">▲TOP</a>\n";
	}
	if ($back_line >= 0) {
		print "[<a href=\"$script?mode=$mode&page=$back_line&word=$enwd&view=$in{'view'}&cond=$in{'cond'}&pastlog=$in{'pastlog'}\">前の$in{'view'}件</a>]\n";
	}
	if ($page_end ne "$end_data") {
		print "[<a href=\"$script?mode=$mode&page=$next_line&word=$enwd&view=$in{'view'}&cond=$in{'cond'}&pastlog=$in{'pastlog'}\">次の$in{'view'}件</a>]\n";
	}

	# ファイルロック解除
	&unlock if ($lockkey);
}

#--------------------#
#  使い方ページ表示  #
#--------------------#
sub howto {
	local($wd1, $wd2, $wd3, $wd4);

	if ($in_email) { $wd1 = "「メールアドレス」"; }
	if ($pastkey) { $wd3 = "また、削除された記事は<a href=\"$script?mode=past\">「過去ログ」</a>へ移動します。"; }
	if ($tagkey) { $wd4 = 'HTMLタグの使用が可能です。'; }
	else { $wd4 = 'HTMLタグの使用はできません。'; }

	&header;
	print <<"EOM";
<table width="100%"><tr><th bgcolor="#008080">
  <font color="#FFFFFF">掲示板の留意事項について</font>
</th></tr></table>
<P>
<b style="text-indent:10">- 投稿する上での注意事項 -</b>
<P>
<UL>
<LI>投稿する上での必須入力項目は<b>「おなまえ」$wd1「タイトル」「メッセージ」</b>です。その他の項目は任意となります。
<LI>投稿時に<B>「パスワード」</B>を入力しておくと、その「パスワード」を使って自分の記事を修正・削除することができます。（但し、「過去ログ」へ移動したものは自分で修正・削除はできません。<A HREF="../formmail/formmail.cgi?Id=webmaster" target="top">管理者</A>へお問い合わせ下さい。）
EOM

	$flag=0;
	if ($in{'view'} eq "hihyouji") {
		$flag=1;
		print "<P><big><font color=$new_color>\n";
	}
	print "<LI>メールアドレスの入力時に、<b>「非表\示」</b>にチェックを入れておくことで、メールアドレスを非表\示とすることができます。（管理者のみにしか分かりません）\n";

	if ($flag) { print "</font></big><P>\n"; }

	print <<"EOM";
<LI>投稿記事の最大保持件数は <b>$max</b>件で、それを超えると古い記事から削除されます。$wd3
<LI>投稿メッセージでは、<b>$wd4</b>
<LI>管理者が著しく不利益と判断する記事や他人を誹謗中傷する記事は予\告なく削除することがあります。
</UL>
<P>
<b style="text-indent:10">- 掲示板の使い方 -</b>
<P>
<UL>
<LI>この掲示板はツリー式掲示板です。どなたかが投稿した記事に対し、簡単に返信メッセージを付けることができます。
<LI>新規の記事投稿はリスト下の「投稿フォーム」から送信して下さい。
<LI>記事を読むには、リスト部にある<b>「題名」</b>をクリックすると内容が表\示されます。またその記事に<b>レス</b>を付けるには、「メッセージ表\示画面」下部の返信用投稿フォームから送信して下さい。
<LI>投稿された記事は、$new_time時間以内はリスト部に <font color=\"$new_color\">$newmark</font> で表\示されます。
<LI>リスト部にて、ツリー先頭部の「題名」をクリックすると関連記事も同時に一括表\示されます。
<LI>メッセージフォーム内の投稿書式には以下の３方法があり、それぞれに適応するラジオボタンを選択します。
  <DL>
  <DT><b>「手動改行」</b>
  <DD>フォーム内の改行位置は、ご自分で適宜改行します。
  <DT><b>「強制改行」</b>
  <DD>フォーム内の改行位置は、フォーム枠の右端で強制的に改行処理します。
  <DT><b>「図表\モード」</b>
  <DD>フォーム内の改行位置や半角スペース位置などをそのままの状態で表\示します。罫線等を使って簡易的な図表\を記述するのに便利です。（HTMLでの&lt;PRE&gt;タグで囲む機能\）
  </DL>
</UL>
</OL>
<hr>
<P>
<center>
<form>
<input type=button value="記事リストにもどる" onClick="history.back()">
</form></center>
</body>
</html>
EOM
	exit;
}

#--------------#
#  自動リンク  #
#--------------#
sub auto_link {
	$_[0] =~ s/([^=^\"]|^)(http\:\/\/[\w\.\~\-\/\?\&\=\;\#\:\%\+]+)/$1<a href=\"$2\" target=\"_blank\">$2<\/a>/g;
}

#--------------#
#  時間の取得  #
#--------------#
sub get_time {
	local($time, $log) = @_;

	if (!$time) { $time = time };
	($sec,$min,$hour,$day,$mon,$year,$wday) = localtime($time);

	if ($log eq "log") {
		$date = sprintf("%02d/%02d-%02d:%02d", $mon+1,$day,$hour,$min);
		return $date;
	} else {
		@week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
		$date = sprintf("%04d/%02d/%02d(%s) %02d:%02d",
				$year+1900,$mon+1,$day,$week[$wday],$hour,$min);
		return $date;
	}
}

#----------------#
#  ホスト名取得  #
#----------------#
sub get_host {
	$host = $ENV{'REMOTE_HOST'};
	$addr = $ENV{'REMOTE_ADDR'};


	if ($host eq "" || $host eq $addr) {
#	$host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2) || $addr;
		use Net::DNS;
		$res = Net::DNS::Resolver->new;
		$query = $res->search($addr, 'PTR');
		$host = "HOST_NOT_DEFINED";
		if ($query) {
			foreach $rr ($query->answer) {
				if ($rr->type eq "PTR") {
					$host = $rr->ptrdname;
				}
			}
		}
	}

# for test
#open WFP, ">>/tmp/hostaddr.log";
#my ($sec,$min,$hour,$day,$mon,$year) = localtime(time);
#$year = $year + 1900;
#$mon = $mon + 1;
#my $now = sprintf("%s-%s-%s %s:%s:%s", $year,$mon,$day,$hour,$min,$sec);
#my $wdat = sprintf("[%s] A=[%s] H=[%s]\n", $now, $addr, $host);
#print WFP $wdat;
#close WFP;
#for test
}

#----------------#
#  過去ログ生成  #
#----------------#
sub pastlog {
	local($past_flag)=0;

	# 過去ログファイルを定義
	open(NO,"$nofile") || &error("Open Error : $nofile");
	$num = <NO>;
	close(NO);
	$num = sprintf("%04d", $num);
	$pastfile  = "$pastdir$num\.cgi";

	# 過去ログを開く
	open(IN,"$pastfile") || &error("Open Error : $pastfile");
	@data = <IN>;
	close(IN);

	# 規定の行数をオーバーすると次ファイルを自動生成
	if ($#data > $max_line) {
		$past_flag=1;

		# カウントファイル更新
		$num++;
		open(NO,">$nofile") || &error("Write Error : $nofile");
		print NO $num;
		close(NO);
		$num = sprintf("%04d", $num);
		$pastfile = "$pastdir$num\.cgi";
		@data=();
	}

	foreach (@PAST) { unshift(@data,$_); }

	# 過去ログを更新
	open(OUT,">$pastfile") || &error("Write Error : $pastfile");
	print OUT @data;
	close(OUT);

	if ($past_flag) { chmod(0666, $pastfile); }
}

#----------------#
#  過去ログ表示  #
#----------------#
sub past_view {
	open(IN,"$nofile") || &error("Open Error : $nofile");
	$pastno = <IN>;
	close(IN);
	$pastno = sprintf("%04d", $pastno);
	if (!$in{'pastlog'}) { $in{'pastlog'} = $pastno; }

	&header;
	print <<"EOM";
[<a href="$script?">掲示板に戻る</a>]
<table width="100%"><tr><th bgcolor="#004080">
  <font color="#FFFFFF">過去ログ [$in{'pastlog'}]</font>
</th></tr></table>
<P><a name="SEARCH"></a>
<form action="$script" method="$method">
<input type=hidden name=mode value=past>
<table cellpadding=0 cellspacing=0>
<tr><td>過去ログ：<select name=pastlog>
EOM

	$pastkey = $pastno;
	while ($pastkey > 0) {
		$pastkey = sprintf("%04d", $pastkey);
		if ($in{'pastlog'} eq "$pastkey") {
			print "<option value=\"$pastkey\" selected>P $pastkey\n";
		} else {
			print "<option value=\"$pastkey\">P $pastkey\n";
		}
		$pastkey--;
	}
	print "</select>\n<input type=submit value='移動'></td></form>\n";
	print "<td width=40></td><td>\n";
	print "<form action=\"$script\" method=GET>\n";
	print "<input type=hidden name=mode value=past>\n";
	print "<input type=hidden name=pastlog value=\"$in{'pastlog'}\">\n";
	print "ワード検索：<input type=text name=word size=30 value=\"$in{'word'}\">\n";
	print "条件：<select name=cond>\n";

	foreach ('AND', 'OR') {
		if ($in{'cond'} eq "$_") {
			print "<option value=\"$_\" selected>$_\n";
		} else {
			print "<option value=\"$_\">$_\n";
		}
	}
	print "</select>\n";
	print "表\示：<select name=view>\n";
	if ($in{'view'} eq "") { $in{'view'} = $p_tree; }
	foreach (5,10,15,20,25,30) {
		if ($in{'view'} eq "$_") {
			print "<option value=\"$_\" selected>$_件\n";
		} else {
			print "<option value=\"$_\">$_件\n";
		}
	}
	print "</select>\n<input type=submit value='検索'></td></form>\n";
	print "</tr></table><hr>\n";

	# ファイルを定義
	$logfile = "$pastdir$in{'pastlog'}\.cgi";

	# ワード検索処理
	if ($in{'word'} ne "") {
		&search;
		print "</body>\n</html>\n";
		exit;
	}

	&ListTreeOpen('past');
	&move_list;
	print "</body>\n</html>\n";
	exit;
}

#----------------------#
#  記事タイトル長調整  #
#----------------------#
sub cut_subject {
	# 制限長に満たないものは戻す
	if (length($_[0]) <= $sub_length) { return $_[0]; }

	# カット処理
	($_[0], $folded) = &fold($_[0], $sub_length);
	$_[0] .= '..';

	return $_[0];
}

#----------------------#
#  ページ移動フォーム  #
#----------------------#
sub move_list {
	$next_page = $page + $p_tree;
	$back_page = $page - $p_tree;

	print "<P><table cellpadding=0 cellspacing=0><tr>\n";
	if ($back_page >= 0) {
		print "<td><form action=\"$script\" method=\"$method\">\n";
		print "<input type=hidden name=pastlog value=\"$in{'pastlog'}\">\n" if ($in{'pastlog'} ne "");
		print "<input type=hidden name=page value=\"$back_page\">\n";
		print "<input type=hidden name=mode value=\"past\">\n" if ($mode eq 'past');
		print "<input type=hidden name=list value=\"$in{'list'}\">\n";
		print "<input type=submit value=\"前ページ\"></td></form>\n";
	}
	if ($next_page < $i) {
		print "<td><form action=\"$script\" method=\"$method\">\n";
		print "<input type=hidden name=pastlog value=\"$in{'pastlog'}\">\n" if ($in{'pastlog'} ne "");
		print "<input type=hidden name=page value=\"$next_page\">\n";
		print "<input type=hidden name=mode value=\"past\">\n" if ($mode eq 'past');
		print "<input type=hidden name=list value=\"$in{'list'}\">\n";
		print "<input type=submit value=\"次ページ\"></td></form>\n";
	}
	print "<td width=10></td><td>[直接移動]\n";

	# ページ移動ボタン表示
	$x=1;
	$y=0;
	while ($i > 0) {
		if ($page eq $y) { print "<b>[$x]</b>\n"; }
		elsif ($in{'pastlog'} ne "") {
			print "[<a href=\"$script?page=$y&list=$in{'list'}&mode=past&pastlog=$in{'pastlog'}\">$x</a>]\n";
		} else {
			print "[<a href=\"$script?page=$y&list=$in{'list'}\">$x</a>]\n";
		}
		$x++;
		$y = $y + $p_tree;
		$i = $i - $p_tree;
	}
	print "</td></tr></table><br>\n";
}

#-----------------#
#  URLエンコード  #
#-----------------#
sub url_enc {
	local($_) = @_;

	s/(\W)/'%' . unpack('H2', $1)/eg;
	s/\s/+/g;
	$_;
}
