#!/usr/bin/perl

#┌─────────────────────────────────
#│ [ YY-BOARD ]
#│ yybbs.cgi - 2007/01/25
#│ Copyright (c) KentWeb
#│ webmaster@kent-web.com
#│ http://www.kent-web.com/
#└─────────────────────────────────

# 外部ファイル取込
require './init.cgi';
require $jcode;

# メイン処理
&decode;
&axsCheck;
if ($mode eq "find") { &find; }
elsif ($mode eq "image") { &image; }
elsif ($mode eq "form") { &form_disp; }
elsif ($mode eq "past") { &past_log; }
elsif ($mode eq "howto") {
	require $howtopl;
	&howto;
} elsif ($mode eq "check") {
	require $checkpl;
	&check;
}
&log_view;

#-------------------------------------------------
#  記事表示部
#-------------------------------------------------
sub log_view {
	# ページ繰越
	local($resfm);
	foreach ( keys(%in) ) {
		if (/^page:(\d+)$/) {
			$page = $1;
		}
		if (/^res:(\d+)$/) {
			$resfm = $1;
			last;
		}
	}
	# 返信フォーム押下
	if ($resfm) { &res_form; }

	# クッキー取得
	local($cnam,$ceml,$curl,$cpwd,$cico,$ccol) = &get_cookie;
	if (!$curl) { $curl = 'http://'; }

	# ヘッダを出力
	if ($ImageView == 1) { &header('ImageUp'); }
	else { &header; }

	# カウンタ処理
	if ($counter) { &counter; }

	# 投稿キー
	local($str_plain,$str_crypt);
	if ($regist_key) {
		require $regkeypl;

		($str_plain,$str_crypt) = &pcp_makekey;
	}

	# タイトル部
	print qq |<div align="center">\n|;
	if ($banner1 ne "<!-- 上部 -->") { print "$banner1<p>\n"; }
	if ($t_img eq '') {
		print qq |<b style="color:$tCol; font-size:$tSize;">$title</b>\n|;
	} else {
		print qq |<img src="$t_img" width="$t_w" height="$t_h" alt="$title">\n|;
	}

	print qq |<hr width="90%">\n|;
	print qq |[<a href="$homepage" target="_top">ホームに戻る</a>]\n|;

	if (!defined($list_type{$in{'list'}})) { $in{'list'} = $view_type; }
	if ($in{'list'} ne "thread") {
		print qq |[<a href="$bbscgi?mode=form&list=$in{'list'}">新規投稿</a>]\n|;
	}

	foreach ( 'thread', 'tree', 'topic' ) {
		next if ($in{'list'} eq $_);

		print qq |[<a href="$bbscgi?list=$_">$list_type{$_}</a>]\n|;
	}

	print <<EOM;
[<a href="$bbscgi?mode=howto&list=$in{'list'}">留意事項</a>]
[<a href="$bbscgi?mode=find&list=$in{'list'}">ワード検索</a>]
EOM

	# 過去ログのリンク部を表示
	if ($pastkey) {
		print qq |[<a href="$bbscgi?mode=past&list=$in{'list'}">過去ログ</a>]\n|;
	}

	print <<EOM;
[<a href="$admincgi">管理用</a>]
<hr width="90%"></div>
EOM

	# 投稿フォーム
	if ($in{'list'} eq 'thread') {
		print qq |<blockquote>\n|;
		print qq |<form method="post" action="$registcgi">\n|;
		print qq |<input type="hidden" name="mode" value="regist">\n|;
		print qq |<input type="hidden" name="page" value="$page">\n|;

		require $formpl;
		&form($cnam,$ceml,$curl,$cpwd,$cico,$ccol,'','');

		print qq |</form></blockquote><br>\n|;
	}

	# 記事を展開
	my $i = 0;
	open(IN,"$logfile") || &error("Open Error: $logfile");
	my $top = <IN>;
	while (<IN>) {
		my ($no,$reno,$dat,$nam,$eml,$sub,$com,$url,$hos,$pw,$col,$ico) = split(/<>/);

		if ($reno eq "") { $i++; }
		if ($i < $page + 1) { next; }
		if ($i > $page + $pglog{$in{'list'}}) { next; }

		# 親記事
		if (!$reno) {
			push(@view,$no);
		# レス記事
		} else {
			$res{$reno} .= "$no,";
		}

		# 題名の長さ
		if (length($sub) > $sub_len*2) {
			$sub = substr($sub, 0, $sub_len*2) . "...";
		}

		# URLリンク
#		if ($autolink) { &auto_link($com); }

		$nam{$no} = $nam;
		$eml{$no} = $eml;
		$sub{$no} = $sub;
		$dat{$no} = $dat;
		$com{$no} = $com;
		$col{$no} = $col;
		$url{$no} = $url;
		$ico{$no} = $ico;
	}
	close(IN);

	# 記事表示
	if ($in{'list'} eq "tree") {
		require $list_log_tree;
		&list_log_tree;

	} elsif ($in{'list'} eq "topic") {
		require $list_log_topic;
		&list_log_topic;

	} else {
		require $list_log_thread;
		&list_log_thread;
	}

	# ページ移動ボタン表示
	if ($page - $pglog{$in{'list'}} >= 0 || $page + $pglog{$in{'list'}} < $i) {
		print qq |<p><table width="90%" align="center">\n|;
		print qq |<tr><td class="n">Page:\n|;
		&mvbtn("$bbscgi?page=", $i, $pglog{$in{'list'}});
		print qq |</td></tr></table>\n|;
	}

	print qq |<div align="center">\n|;

	# ユーザメンテフォーム（トピック表示以外）
	if ($in{'list'} ne "topic") {
		print qq |<form action="$registcgi" method="post">\n|;
		print qq |<input type="hidden" name="list" value="$in{'list'}">\n|;
		print qq |<select name="mode" class="f">\n|;
		print qq |<option value="edit">修正\n|;
		print qq |<option value="dele">削除</select>\n|;
		print qq |No.<input type="text" name="no" size="3" class="f" style="ime-mode:inactive">\n|;
		print qq |暗証キー<input type="password" name="pwd" size="4" maxlength="8" class="f">\n|;
		print qq |<input type="submit" value="送信"></form>\n|;
	}

	# 著作権表示（削除不可）: 但し、MakiMakiさんの画像を使用しない場合に限り、
	# MakiMakiさんのリンクを外すことは可能です。
	print <<EOM;
$banner2
<p>
<!-- $ver -->
<span style="font-size:10px; font-family:Verdana,Helvetica,Arial;">
- <a href="http://www.kent-web.com/" target="_top">YY-BOARD</a> - 
icon:<a href="http://homepage3.nifty.com/makiz/" target="_top">MakiMaki</a>
</span>
</div>
</body>
</html>
EOM
	exit;
}

#-------------------------------------------------
#  返信フォーム
#-------------------------------------------------
sub res_form {
	# 投稿キー
	local($str_plain,$str_crypt);
	if ($regist_key) {
		require $regkeypl;

		($str_plain,$str_crypt) = &pcp_makekey;
	}
	$in{'no'} = $resfm;

	# クッキーを取得
	local($cnam,$ceml,$curl,$cpwd,$cico,$ccol) = &get_cookie;
	if (!$curl) { $curl = 'http://'; }

	# ログを読み込み
	my $flg;
	open(IN,"$logfile") || &error("Open Error: $logfile");
	my $top = <IN>;

	# ヘッダを出力
	if ($ImageView == 1) { &header('ImageUp'); }
	else { &header; }

	# 関連記事出力
	print <<EOM;
<form>
<input type="button" value="&lt; 戻る" onclick="history.back()">
</form>
▽以下は記事No.<B>$in{'no'}</B> に関する<a href="#RES">返信フォーム</a>です。
<dl>
EOM

	while (<IN>) {
		my ($no,$reno,$dat,$nam,$eml,$sub,$com,$url) = split(/<>/);
		if ($in{'no'} == $no && $reno) { $flg++; }
		if ($in{'no'} == $no || $in{'no'} == $reno) {

			if ($in{'no'} == $no) { $resub = $sub; }
			if ($url) { $url = "&lt;<a href=\"$url\">Home</a>&gt;"; }
			if ($reno) { print '&nbsp;&nbsp;'; }

			print "<dt><hr><font color=\"$subcol\"><b>$sub</b></font>\n";
			print "投稿者：<b>$nam</b> 投稿日：$dat $url ";
			print "<font color=\"$subcol\">No.$no</font><br><br>\n";
			print "<dd>$com\n";
		}
	}
	close(IN);

	if ($flg) { &error("不正な返信要求です"); }

	# タイトル名
	if ($resub !~ /^Re\:/) { $resub = "Re: $resub"; }

	print <<"EOM";
<dt><hr>
</dl>
<a name="RES"></a>
<form action="$registcgi" method="post">
<input type="hidden" name="mode" value="regist">
<input type="hidden" name="reno" value="$in{'no'}">
<input type="hidden" name="page" value="$page">
<blockquote>
EOM

	require $formpl;
	&form($cnam,$ceml,$curl,$cpwd,$cico,$ccol,$resub,'');

	print <<EOM;
</form>
</blockquote>
</body>
</html>
EOM
	exit;
}

#-------------------------------------------------
#  ワード検索
#-------------------------------------------------
sub find {
	&header;
	print <<EOM;
<form action="$bbscgi">
<input type="hidden" name="list" value="$in{'list'}">
<input type="submit" value="&lt; 戻る">
</form>
<ul>
<li>キーワードを入力し、「条件」「表\示」を選択して検索ボタンを押して下さい。
<li>キーワードはスペースで区切って複数指定することができます。
<p>
<form action="$bbscgi" method="post">
<input type="hidden" name="mode" value="find">
<input type="hidden" name="list" value="$in{'list'}">
キーワード <input type="text" name="word" size="35" value="$in{'word'}" class="f">
条件 <select name="cond" class="f">
EOM

	if (!$in{'cond'}) { $in{'cond'} = "AND"; }
	foreach ("AND", "OR") {
		if ($in{'cond'} eq $_) {
			print "<option value=\"$_\" selected>$_\n";
		} else {
			print "<option value=\"$_\">$_\n";
		}
	}

	if (!$in{'view'}) { $in{'view'} = 10; }
	print qq |</select> 表\示 <select name="view" class="f">\n|;

	foreach (10,15,20,25) {
		if ($in{'view'} == $_) {
			print "<option value=\"$_\" selected>$_件\n";
		} else {
			print "<option value=\"$_\">$_件\n";
		}
	}

	print <<EOM;
</select>
<input type="submit" value="検索">
</form>
</ul>
EOM

	# 検索実行
	if ($in{'word'} ne "") {
		($i,$next,$back) = &search($logfile,$in{'word'},$in{'view'},$in{'cond'});

		$enwd = &url_enc($in{'word'});
		if ($back >= 0) {
			print "[<a href=\"$bbscgi?mode=find&page=$back&word=$enwd&view=$in{'view'}&cond=$in{'cond'}&list=$in{'list'}\">前の$in{'view'}件</a>]\n";
		}
		if ($next < $i) {
			print "[<a href=\"$bbscgi?mode=find&page=$next&word=$enwd&view=$in{'view'}&cond=$in{'cond'}&list=$in{'list'}\">次の$in{'view'}件</a>]\n";
		}
	}

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

#-------------------------------------------------
#  投稿画面
#-------------------------------------------------
sub form_disp {
	# 投稿キー
	local($str_plain,$str_crypt);
	if ($regist_key) {
		require $regkeypl;

		($str_plain,$str_crypt) = &pcp_makekey;
	}

	# クッキーを取得
	local($cnam,$ceml,$curl,$cpwd,$cico,$ccol) = &get_cookie;
	if (!$curl) { $curl = 'http://'; }

	# ヘッダを出力
	if ($ImageView == 1) { &header('ImageUp'); }
	else { &header; }

	# 関連記事出力
	print <<EOM;
<form>
<input type="button" value="&lt; 戻る" onclick="history.back()">
</form>
▼新規投稿フォーム
<hr>
EOM

	print <<"EOM";
<a name="RES"></a>
<form action="$registcgi" method="post">
<input type="hidden" name="mode" value="regist">
<input type="hidden" name="reno" value="$in{'no'}">
<input type="hidden" name="page" value="$page">
<input type="hidden" name="list" value="$in{'list'}">
<blockquote>
EOM

	require $formpl;
	&form($cnam,$ceml,$curl,$cpwd,$cico,$ccol,'','');

	print <<EOM;
</form>
</blockquote>
</body>
</html>
EOM
	exit;
}

#-------------------------------------------------
#  過去ログ
#-------------------------------------------------
sub past_log {
	open(IN,"$nofile") || &error("Open Error: $nofile");
	my $num = <IN>;
	close(IN);

	$in{'log'} =~ s/\D//g;
	if (!$in{'log'}) { $in{'log'} = $num; }

	&header;
	print <<"EOM";
<form action="$bbscgi">
<input type="hidden" name="list" value="$in{'list'}">
<input type="submit" value="&lt; 戻る">
</form>
<form action="$bbscgi" method="post">
<input type="hidden" name="mode" value="$mode">
<input type="hidden" name="list" value="$in{'list'}">
<table border="0">
<tr><td><b>過去ログ</b> <select name="log" class="f">
EOM

	# 過去ログ選択
	for ( my $i = $num; $i > 0; --$i ) {
		$i = sprintf("%04d", $i);
		next unless (-e "$pastdir/$i.cgi");

		if ($in{'log'} == $i) {
			print "<option value=\"$i\" selected>$i\n";
		} else {
			print "<option value=\"$i\">$i\n";
		}
	}

	print <<EOM;
</select>
<input type="submit" value="移動"></td></form>
<td width="15"></td><td>
<form action="$bbscgi" method="post">
<input type="hidden" name="mode" value="$mode">
<input type="hidden" name="list" value="$in{'list'}">
<input type="hidden" name="log" value="$in{'log'}">
キーワード <input type="text" name="word" size="35" value="$in{'word'}" class="f">
条件 <select name="cond" class="f">
EOM

	if (!$in{'cond'}) { $in{'cond'} = "AND"; }
	foreach ("AND", "OR") {
		if ($in{'cond'} eq $_) {
			print "<option value=\"$_\" selected>$_\n";
		} else {
			print "<option value=\"$_\">$_\n";
		}
	}

	print qq |</select> 表\示 <select name="view" class="f">\n|;

	if (!$in{'view'}) { $in{'view'} = 10; }
	foreach (10,15,20,25) {
		if ($in{'view'} == $_) {
			print "<option value=\"$_\" selected>$_件\n";
		} else {
			print "<option value=\"$_\">$_件\n";
		}
	}

	print <<EOM;
</select>
<input type="submit" value="検索"></td>
</form>
</tr></table>
EOM

	my $file = sprintf("%s/%04d.cgi", $pastdir,$in{'log'});

	# 検索処理
	if ($in{'word'} ne "") {

		# 検索
		my ($i, $next, $back) = &search($file, $in{'word'}, $in{'view'}, $in{'cond'}, 'past');

		# ページ繰り越し
		my $enwd = &url_enc($in{'word'});
		if ($back >= 0) {
			print "[<a href=\"$bbscgi?mode=$mode&log=$in{'log'}&page=$back&word=$enwd&view=$in{'view'}&cond=$in{'cond'}&list=$in{'list'}\">前の$in{'view'}件</a>]\n";
		}
		if ($next < $i) {
			print "[<a href=\"$bbscgi?mode=$mode&log=$in{'log'}&page=$next&word=$enwd&view=$in{'view'}&cond=$in{'cond'}&list=$in{'list'}\">次の$in{'view'}件</a>]\n";
		}

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

	print "<dl>\n";

	my $i = 0;
	open(IN,"$file") || &error("Open Error: $file");
	while (<IN>) {
		my ($no,$re,$dat,$nam,$eml,$sub,$com,$url,$hos,$pw,$col,$ico) = split(/<>/);

		if ($re eq "") { $i++; }
		if ($i < $page + 1) { next; }
		if ($i > $page + $pastView) { next; }

		if ($eml) { $nam = "<a href=\"mailto:$eml\">$nam</a>"; }
		if ($url) { $url = "&lt;<a href=\"$url\" target=\"_blank\">URL</a>&gt;"; }

		if ($re eq "") { print "<dt><hr>"; } else { print "<dd>"; }

		print qq |<b style="color:$subcol">$sub</b>&nbsp;|;
		print qq |<b>$nam</b> - $dat $url <span style="color:$subcol">No.$no</span><br><br>\n|;

		if ($ico) {
			print qq |<table><tr><td><img src="$imgurl/$ico"></td>|;
			print qq |<td width="10"></td><td style="color:$col">$com</td>|;
			print qq |</tr></table>\n|;
		} else {
			print qq |<dd style="color:$col">$com</dd>\n|;
		}
	}
	close(IN);

	print <<EOM;
<dt><hr>
</dl>
EOM

	# ページ移動ボタン表示
	if ($page - $pastView >= 0 || $page + $pastView < $i) {
		&mvbtn("$bbscgi?mode=$mode&log=$in{'log'}&page=", $i, $pastView);
	}

	print <<EOM;
</body>
</html>
EOM
	exit;
}

#-------------------------------------------------
#  カウンタ処理
#-------------------------------------------------
sub counter {
	local($count, $cntup, @count);

	# 閲覧時のみカウントアップ
	if ($mode eq '') { $cntup = 1; } else { $cntup = 0; }

	# カウントファイルを読みこみ
	open(LOG,"+< $cntfile") || &error("Open Error: $cntfile");
	eval "flock(LOG, 2);";
	$count = <LOG>;

	# IPチェックとログ破損チェック
	local($cnt, $ip) = split(/:/, $count);
	if ($addr eq $ip || $cnt eq "") { $cntup = 0; }

	# カウントアップ
	if ($cntup) {
		$cnt++;
		truncate(LOG, 0);
		seek(LOG, 0, 0);
		print LOG "$cnt:$addr";
	}
	close(LOG);

	# 桁数調整
	while(length($cnt) < $mini_fig) { $cnt = '0' . $cnt; }
	@count = split(//, $cnt);

	# GIFカウンタ表示
	if ($counter == 2) {
		foreach (0 .. $#count) {
			print "<img src=\"$gif_path/$count[$_]\.gif\" alt=\"$count[$_]\" width=\"$mini_w\" height=\"$mini_h\">";
		}
	# テキストカウンタ表示
	} else {
		print "<font color=\"$cntcol\" face=\"Verdana,Helvetica,Arial\">$cnt</font><br>\n";
	}
}

#-------------------------------------------------
#  画像イメージ表示
#-------------------------------------------------
sub image {
	my @ico1 = split(/\s+/, $ico1);
	my @ico2 = split(/\s+/, $ico2);

	&header;
	print <<EOM;
<div align="center">
<h4>画像イメージ</h4>
<table border="1" cellpadding="5" cellspacing="0" bgcolor="$tblcol">
EOM

	my $i = 0;
	foreach (0 .. $#ico1) {
		$i++;

		if ($i % 5 == 1) {
			print "<tr>\n";
		}
		print qq |<th><img src="$imgurl/$ico1[$_]" align="middle" alt="$ico1[$_]">$ico2[$_]</th>\n|;

		if ($i % 5 == 0) {
			print "</tr>\n";
		}
	}
	while ( $i % 5 != 0 ) {
		print qq |<td><br></td>|;
		$i++;
	}

	print <<EOM;
</table>
<br>
<form>
<input type="button" value=" 閉じる " onclick="top.close();">
</form>
</div>
</body>
</html>
EOM
	exit;
}

#-------------------------------------------------
#  移動ボタン
#-------------------------------------------------
sub mvbtn {
	local($link,$i,$view) = @_;
	local($start,$end,$x,$y,$bk_bl,$fw_bl);

	if ($in{'bl'}) {
		$start = $in{'bl'}*10 + 1;
		$end   = $start + 9;
	} else {
		$in{'bl'} = 0;
		$start = 1;
		$end   = 10;
	}

	$x = 1; $y = 0;
	while ($i > 0) {
		# 当ページ
		if ($page == $y) {

			print qq {| <b style="color:red" class="n">$x</b>\n};

		# 切替ページ
		} elsif ($x >= $start && $x <= $end) {

			print "| <a href=\"$link$y&bl=$in{'bl'}&list=$in{'list'}\" class=n>$x</a>\n";

		# 前ブロック
		} elsif ($x == $start-1) {

			$bk_bl = $in{'bl'}-1;
			print "| <a href=\"$link$y&bl=$bk_bl&list=$in{'list'}\">←</a>\n";

		# 次ブロック
		} elsif ($x == $end+1) {

			$fw_bl = $in{'bl'}+1;
			print "| <a href=\"$link$y&bl=$fw_bl&list=$in{'list'}\">→</a>\n";
		}

		$x++;
		$y += $view;
		$i -= $view;
	}

	print "|\n";
}

#-------------------------------------------------
#  検索処理
#-------------------------------------------------
sub search {
	local($file, $word, $view, $cond, $job) = @_;

	# キーワードを配列化
	$word =~ s/\x81\x40/ /g;
	my @wd = split(/\s+/, $word);

	# ファイル展開
	print "<dl>\n";
	my $i = 0;
	open(IN,"$file") || &error("Open Error: $file");
	my $top = <IN> if ($job ne "past");
	while (<IN>) {
		my $flg;
		foreach my $wd (@wd) {
			if (index($_,$wd) >= 0) {
				$flg++;
				if ($cond eq 'OR') { last; }
			} else {
				if ($cond eq 'AND') { $flg = 0; last; }
			}
		}

		# ヒットした場合
		if ($flg) {
			$i++;
			next if ($i < $page + 1);
			next if ($i > $page + $view);

			my ($no,$reno,$dat,$nam,$eml,$sub,$com,$url,$hos,$pw,$col,$ico) = split(/<>/);
			if ($eml) { $nam = "<a href=\"mailto:$eml\">$nam</a>"; }
			if ($url) { $url = "&lt;<a href=\"$url\" target=\"_blank\">Home</a>&gt;"; }

			# 結果を表示
			print "<dt><hr>[<b>$no</b>] <b style=\"color:$subcol\">$sub</b> ";
			print "投稿者：<b>$nam</b> 投稿日：$dat $url<br><br>\n";
			print "<dd style=\"color:$col\">$com\n";
		}
	}
	close(IN);

	print <<EOM;
<dt><hr>
検索結果：<b>$i</b>件
</dl>
EOM

	my $next = $page + $view;
	my $back = $page - $view;
	return ($i, $next, $back);
}

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

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

