#!/usr/bin/perl

#******************************************************************************
#lresbbs.cgi - Line Response BBS Ver.1.21
#
#Version   	:1.21
#modified  	:2000/12/01
#Copyright 	:The Room
#E-Mail		:dream@lib.net
#URL		:http://dream.lib.net/room/
#
#これはフリー素材です。
#転載・商用目的の利用の際には、メールをお願いします。
#
#******************************************************************************
#1行目のperlのディレクトリ指定は、サーバによって異なります。
#詳しくは、管理者にお聞きください。
#******************************************************************************
#画面設定
#
#タイトル
$title = "FORコミニケット掲示板";
#
#BODYタグ
$bodytag='<body text=#000000 bgcolor=#ffffff link=#303060 vlink=#303060 alink=#8080cf>';
#
#ページ上部に表示する題名
$pagetop = '<div align=center><font color=#6060ff size=6>FORコミニケット掲示板</font></div>';
#
#ホームページURL
#＊Back to Homeのリンクで戻るところ
#設定しない場合とリンクは表示されません。
$homeback = "http://www.for.jp/comi/";
#
#******************************************************************************
#メッセージ欄の色
#
$msgcl1 = "#f0f0ff";	#題名部分の背景色
$msgcl2 = "#e0e0ff";	#名前部分の背景色
$msgcl3 = "#d0d0ff";	#時間表示部分の背景色
$msgcl4 = "#c0c0ff";	#本文の背景色
#
#******************************************************************************
#入力欄の色
#
$entercl1 = "#f0f0ff";	#名前入力欄の背景色
$entercl2 = "#e8e8ff";	#E-Mail入力欄の背景色
$entercl3 = "#e0e0ff";	#URL入力欄の背景色
$entercl4 = "#d8d8ff";	#題名入力欄の背景色
$entercl5 = "#d0d0ff";	#メッセージ入力欄の背景色
$entercl6 = "#c8c8ff";	#削除キー入力欄の背景色
#
#******************************************************************************
#エラーメッセージ表示の色
#
$error1="#d0d0ff";#エラー表示の枠の色
$error2="#ffffff";#エラー表示の枠内の色
#
#******************************************************************************

#
#スタイルシート設定
#＊「$sheet = <<EOD;」から「EOD」の間の行にスタイルシートを書きます
#＊inputは入力するボックス、buttonはSubmitなどのボタンを表します。
#＊使用しない場合は、削除してください。
$sheet = <<EOD;	
<style type = "text/css">
BODY,TD,TH{font-size: 10pt;}
.input 	{border-color:a0a0ff;
		border-style:solid solid solid solid;
		}
.button	{border-color:6060ff;
		border-style:solid solid solid solid;
		background-color: d0d0ff;
		color: 0000ff;
		}
</style>
EOD
#
#******************************************************************************
#
#マスターパスワード
#＊すべての記事の削除キーに使えます。
$adminpass = "yuuGiri1011";
#
#ログ保存ファイル名
$logfile = "./log.dat";
#
#親記事のログ保存の最大数
$maxlog = 50;
#
#１ページに表示する最大記事数
$maxpage = 10;
#
#名前入力が無い場合の名前
#＊設定しないと名前の入力が必須となります。
$newname = "";
#
#題名入力が無い場合の題名
#＊設定しないと題名の入力が必須となります。
$newsubject = "";

#レスがついた記事を一番上に持ってくるなら1を。
$resmove = 1;

#
#時刻設定
sub timeset{$timeword = "$month/$day($week) $hour:$min";}
#            	         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#			#２つの " の間に時刻表示のフォーマットを書きます
#			#以下の変数を書くと、表示されるときに
#			#その値が表示されます
#
#			# $year 年
#			# $month月
#			# $day	日
#			# $hour	時
#			# $min	分
#			# $sec	秒
#		        # $week 曜日

#時刻表示のゼロ補完の有無
# 10以下を表示するときは 04 のように頭に 0 を追加します。
# この機能を使う場合は 1 を、使わない場合は 0 を。
$spzero[0] = 0;#月の補完
$spzero[1] = 0;#日の補完
$spzero[2] = 0;#時の補完
$spzero[3] = 1;#分の補完
$spzero[4] = 0;#秒の補完

#曜日の設定
# 日〜土の順番です。
@weekday = ("Sun","Mon","Tue","Wed","Thr","Fri","Sat");
#
#******************************************************************************
#
$ipindicate = 1;	#ソースにIP/ホスト名を表示するときは1を。
#
$jcode = './jcode.pl';	#jcode.plの位置
#
@denyhost = ();		#アクセス拒否をするホスト名を入力します。
#			#@denyhost = ("anonymizer","cache*.*",……);
#			#このように入力していきます。
#			#例のように、ワイルドカードも使用できます。
#
@permittag = ("i","b","font");#使用を許可するタグを書きます。
#			#全て不許可の場合は、
#			# @permittag = ();
#			#としてください。
#			#
#			# a タグ・img タグを下の自動リンクを同時に使用すると、
#			#うまく動作しない場合があります。
#
$autolink = 1;	#URLの書きこみに自動的にリンクを貼るなら1を。
#
$referercheck = 0;	#別ページからの投稿を禁止する場合は1を。
#
$double = 1;	#二重投稿を禁止する場合は1を。
#
#******************************************************************************

#jcode.plの読みこみ
require $jcode;
$ENV{'TZ'}="JST-9";
srand;

#データ受け取り
$cl = $ENV{"CONTENT_LENGTH"};
if( $cl > 0 ){
	read(STDIN, $qs, $cl );
}else{
	$qs = $ENV{"QUERY_STRING"};
	}

@contents = split(/&/,$qs);
foreach $i (0 .. $#contents) {
	local($key,$text)= split(/=/,$contents[$i]);
	$text =~ s/\+/ /g;
	$text =~ s/%(..)/pack("c",hex($1))/ge;
	$text =~ s/\r\n/\n/g;
	&jcode'convert(*text,'sjis');
	$act = $text if $key eq 'act';
	$page = $text if $key eq 'page';
	$name = $text if $key eq 'name';
	$email = $text if $key eq 'email';
	$url = $text if $key eq 'url';
	$subject = $text if $key eq 'subject';
	$delkey = $text if $key eq 'delkey';
	$msg = $text if $key eq 'msg';
	$pass = $text if $key eq 'pass';
	$num = $text if $key eq 'num';
	$chdel = $text if $key eq 'chdel';
	}

#環境変数取得
$ip = $ENV{'REMOTE_ADDR'};
$host = gethostbyaddr(pack("C4", split(/\./, $ip)), 2);
$host ||= $ENV{'REMOTE_HOST'};
$host ||= $ip;
$referer=$ENV{'HTTP_REFERER'};
$script=$ENV{'SCRIPT_NAME'};

#アクセス拒否チェック
foreach (@denyhost){
	if ($host =~ /$_/i){
		&error("あなたの使用しているホストからのアクセスは禁止されています。");
		last;
		}
	}

#データチェック
$page||=0;

if (($act eq "write") || ($act eq "reswrite")){
	$a1 = $msg;
	$a1 =~ s/[\r\n\t]//g;
	$act = "" if $a1 eq "";
	}


#クッキー取得
for $xx (split(/; */, $ENV{'HTTP_COOKIE'})) {
	($chname, $value) = split(/=/, $xx);
	$value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
	$cookie{$chname} = $value;
	}
$name||=$cookie{'name'};
$email||=$cookie{'email'};
$url||=$cookie{'url'};
$delkey||=$cookie{'delkey'};

#命令分岐
if ($act eq "delete"){&delete;}


$name||=$newname;
$subject||=$newsubject;

@log=();
$nextflag = 0;
$prevflag = 1 if $page != 0;
if (($act eq "write") || ($act eq "reswrite")){
	&error("名前を入力してください。") if $name eq "";
	&error("題名を入力してください。") if ($subject eq "") && ($act eq "write");
	&error("別ページからの投稿は禁止されています。") if ($referercheck == 1) && ($referer !~ /$script/i);
	while(1){if (!(chomp($msg))){last;}}

	#許可タグ以外を無効にする
	$msg =~ s/[\t\a]//g;
	$msg =~ s/&/&amp;/g;
	$msg =~ s/</\t/g;
	$msg =~ s/>/\a/g;
	foreach (@permittag){
		$msg =~ s/\t(\/?$_)\a/<$1>/g;
		$msg =~ s/\t$_ ([^\a]*)\a/<$_ $1>/g;
		}
	$msg =~ s/\t/&lt;/g;
	$msg =~ s/\a/&gt;/g;
	$msg =~ s/&amp;/&/g;

	foreach (@permittag){
	if (($msg =~ /<$_/) && ($msg !~ /<\/$_/)){$msg .="<\/$_>";}
		}

	#URLには自動的にリンクを行う
	if ($autolink == 1){
		$msg =~ s/(http:\/\/[a-zA-Z0-9\.\/\-+#_?~&%=^\@:;]+)/<A HREF="$1">$1<\/A>/g;
		}
	$msg =~ s/\n/<br>/g;
	$subject =~ s/</&lt;/g;
	$subject =~ s/>/&gt;/g;
	if ($url eq "http://"){$url = "";}

	#ファイル読みこみ
	open (IO,"+<$logfile");
	eval{flock(IO,2)};

	if ($act eq "write"){
		#親記事書きこみ
		#最大表示数-1の記事を@y1へ
		$a3=1;
		$a2=$a4=0;
		@y1=();
		while (<IO>){
			@y2=split(/<>/,$_);
			if ($y2[0] > $a2){$a2=$y2[0];}
			if ($y2[1] == 0){$a3=$y2[0];$a4++;}
			if ($a4 < $maxpage){push(@y1,$_);}
			push(@log,$_);
			}
		$a2++;
		@y2 = split(/<>/,$log[0]);

		#二重書きこみの禁止
		if (($double == 1) && ($msg eq $y2[8])){close(IO);&error("二重投稿は禁止されています。");}

		#ログ追加
		unshift(@log,"$a2<>0<>$name<>$email<>$url<>" . time() . "<>$delkey<>$subject<>$msg<>$ip/$host<>\n");
		unshift(@y1,"$a2<>0<>$name<>$email<>$url<>" . time() . "<>$delkey<>$subject<>$msg<>$ip/$host<>\n");

		#書きこみ
		truncate(IO,0);
		seek(IO,0,0);

		if ($a4+1 > $maxlog){
			foreach(@log){
				last if $_ =~ /^$a3<>/i;
				print IO $_;
				}
			}else{
			print IO @log;
			}
		close(IO);

		if ($log[$maxpage] ne ""){$nextflag = 1;}
		@log=@y1;
		}else{
		#レス記事書きこみ
		
		$a2=$a3=0;
		$a4="";
		@log1=@log2=@log3=@y1=();
		while(<IO>){
			@y2=split(/<>/,$_);
			if ($y2[0] > $a3){$a3=$y2[0];$a4=$y2[8];}
			if ($y2[0] == $num){
				$a2=1;
				}
			elsif (($y2[1] == 0) && ($a2 == 1)){
				$a2=2;
				}
			push(@log1,$_) if $a2==0;
			push(@log2,$_) if $a2==1;
			push(@log3,$_) if $a2==2;
			}
		#二重書きこみの禁止
		if (($double == 1) && ($msg eq $a4)){close(IO);&error("二重投稿は禁止されています。");}

		$a3++;
		#ログ追加
		@y2=split(/<>/,$log2[$#log2]);
		push(@log2,"$a3<>" . ($y2[1]+1) . "<>$name<>$email<>$url<>" . time() . "<>$delkey<>$subject<>$msg<>$ip/$host<>\n");

		#ファイル書きこみ
		truncate(IO,0);
		seek(IO,0,0);
		if ($resmove == 1){
			foreach(@log2){print IO $_;push(@y1,$_);}
			foreach(@log1){print IO $_;push(@y1,$_);}
			foreach(@log3){print IO $_;push(@y1,$_);}
			}else{
			foreach(@log1){print IO $_;push(@y1,$_);}
			foreach(@log2){print IO $_;push(@y1,$_);}
			foreach(@log3){print IO $_;push(@y1,$_);}
			}
		close (IO);
		#表示ログ取得
		$a1=-1;
		for (0 .. $#y1){
			@y2=split(/<>/,$log[$_]);
			$a1++ if $y2[1] == 0;
			last if $a1 >= $maxpage;
			if ($a1 >= $maxpage){
				push(@log,$log[$_]);
				}
			}

		$a1=$nextflag=0;
		for(0 .. $#y1){
			@y2=split(/<>/,$y1[$_]);
			$a1++ if $y2[1] == 0;
			if ($a1 > $maxpage){
				$nextflag = 1;
				last;
				}
			push(@log,$y1[$_]);
			}
		}
	}else{
	#必要な部分だけログ読み
	$a1=-1;
	open (IN,"$logfile");
	eval{flock(IN,1)};
	while(<IN>){
		@y2=split(/<>/,$_);
		$a1++ if $y2[1] == 0;
		last if $a1 >= ($page+1)*$maxpage;
		if ($a1 >= $page*$maxpage){
			push(@log,$_);
			}
		}
	$a1="";
	$a1=<IN>;
	close (IN);
	if ($a1 ne ""){$nextflag = 1;}
	}

#クッキー書きこみ
print "Set-Cookie:name=$name; expires=Thu, 1-Jan-2030 00:00:00 GMT;\n";
print "Set-Cookie:email=$email; expires=Thu, 1-Jan-2030 00:00:00 GMT;\n";
print "Set-Cookie:url=$url; expires=Thu, 1-Jan-2030 00:00:00 GMT;\n";
print "Set-Cookie:delkey=$delkey; expires=Thu, 1-Jan-2030 00:00:00 GMT;\n";

&hphead;

#ここでメッセージ入力フォームを表示しています。
# formタグ・inputタグ・textareaタグは基本的には変更しないでください。
# inputタグのsize・textareaタグのcols/rowsは変更してもOKです。

print <<EOD;
<form method="post" action="./lresbbs.cgi">
<table border=0 align=center>
<tr bgcolor=$entercl1><td align="right">NAME : <input type="text" class="input" name="name" size="20" value="$name">&nbsp;</td></tr>
<tr bgcolor=$entercl2><td align="right">E-Mail : <input type="text" class="input" name="email" size="20" value="$email">&nbsp;</td></tr>
<tr bgcolor=$entercl3><td align="right">URL : <input type="text" class="input" name="url" size="20" value="$url">&nbsp;</td></tr>
<tr bgcolor=$entercl4><td align="left">&nbsp;Subject : <input type="text" class="input" name="subject" size="30">&nbsp;</td></tr>
<tr bgcolor=$entercl5><td align="left">&nbsp;Comment : <br>
&nbsp;<textarea name="msg" class="input" cols="50" rows="6"></textarea>&nbsp;</th></tr>
<tr bgcolor=$entercl6><td align="left">&nbsp;Delete Key : <input type="password" class="input" name="delkey" size="10" value="$delkey"></td></tr>
<tr bgcolor=$entercl6><td align="center"><input type="submit" class="button" value="Submit"><input type="reset" class="button" value="Reset"></td></tr>
</table>
<input type="hidden" name="act" value="write">
<input type="hidden" name="page" value="0">
</form>
EOD
#ここまで

if ($homeback ne ""){
	print "<div align=\"center\"><a href=\"$homeback\">&lt;&lt;Back To Home</a></div>\n";
	}
print "<br><br>";

$flag = 0;

for (0 .. $#log){
	last if $log[$_] eq "";
	&mesindi($log[$_]);
	}
if ($log[0] ne ""){
print <<EOD;
<hr color="$msgcl1\" width=100% align=center>
Name:<input type="text" class="input" name="name" size="6" value="$name">&nbsp;
Res:<input type="text" name="msg" class="input" size="30">
Del Key:<input type="password" class="input" name="delkey" size="6" value="$delkey">
<input type="hidden" class="input" name="email" value="$email">
<input type="hidden" class="input" name="url" value="$url">
<input type="submit" class="button" value="Submit">
<input type="hidden" name="act" value="reswrite">
<input type="hidden" name="page" value="0">
<input type="hidden" name="num" value="$num">
</td></form></tr></table>
</td></tr></table>
</td></tr></table><br>
EOD
	}

#NEXT/BACKのボタン表示
print "<table border=0 align=center><tr>";
if ($prevflag == 1){
	$a1 = $page-1;
print <<EOD;
<td>
<form method="post" action="./lresbbs.cgi">
<input type="hidden" name="page" value="$a1">
<input type="submit" class="button" value="Prev">
</form>
</td>
EOD
	}
if ($nextflag == 1){
	$a1 = $page+1;
print <<EOD;
<td>
<form method="post" action="./lresbbs.cgi">
<input type="hidden" name="page" value="$a1">
<input type="submit" class="button" value="Next">
</form>
</td>
EOD
	}


#削除フォーム表示
print <<EOD;
</tr>
</table>
<table align=center>
<form method="post" action="./lresbbs.cgi">
<tr><td bgcolor=$msgcl1 align=center>
記事番号：<input type="text" class="input" name="chdel" size=4>
削除キー：<input type="password" class="input" name="pass" size=9>
</td>
</tr>
<tr>
<td bgcolor=$msgcl2 align=center>
<input type="submit" class="button" value="記事削除">
<input type="hidden" name="act" value="delete">
</td>
</tr>
</form>
</table>
EOD

&hpfoot;

#******************************************************************************
sub mesindi{
#記事表示
my @y2 = split(/<>/,$_[0]);
my $a1 = "";

#時間形式
($sec,$min,$hour,$day,$month,$year,$week) = gmtime($y2[5]+32400);
$month++;
$year += 1900;
if (($spzero[4] == 1) && ($sec < 10)){$sec="0$sec";}
if (($spzero[3] == 1) && ($min < 10)){$min="0$min";}
if (($spzero[2] == 1) && ($hour < 10)){$hour="0$hour";}
if (($spzero[1] == 1) && ($month < 10)){$month ="0$month";}
if (($spzero[0] == 1) && ($day < 10)){$day ="0$day";}
$week=$weekday[$week];
&timeset;


if ($y2[3] ne ""){$a1 = "[<a href=\"mailto:$y2[3]\">Mail</a>]";}
if ($y2[4] ne ""){$a1 .= "[<a href=\"$y2[4]\" target=\"_blank\">HomePage</a>]";}
if ($a1 ne ""){$a1="&nbsp;$a1";}

if ($ipindicate == 1){$y2[8].="\n<!--$y2[9]-->\n";}

if ($y2[1] == 0){ 
	if ($flag == 1){
print <<EOD;
<hr color="$msgcl1\" width=100% align=center>
Name:<input type="text" class="input" name="name" size="6" value="$name">&nbsp;
Res:<input type="text" name="msg" class="input" size="30">
Del Key:<input type="password" class="input" name="delkey" size="6" value="$delkey">
<input type="hidden" class="input" name="email" value="$email">
<input type="hidden" class="input" name="url" value="$url">
<input type="submit" class="button" value="Submit">
<input type="hidden" name="act" value="reswrite">
<input type="hidden" name="page" value="0">
<input type="hidden" name="num" value="$num">
</td></form></tr></table>
</td></tr></table>
</td></tr></table><br>
EOD
		}else{
		$flag= 1;
		}
$num=$y2[0];

#親記事表示
print <<EOD;
<table border=0 width="70%" align=center>
<tr><td bgcolor="$msgcl1" align="left">
&nbsp;<b>[$y2[0]]$y2[7]</b>
</td></tr>
<tr><td bgcolor="$msgcl2" align="right">
<b>$y2[2]</b>$a1&nbsp;
</td></tr>
<tr><td bgcolor="$msgcl3" align="right">
$timeword&nbsp;</td></tr>
<tr><td bgcolor="$msgcl4" align="center">
<table width="98%">
<tr><td align="left">
$y2[8]
<br>
<table align=center width=98%>
<tr>
<form method="post" action="./lresbbs.cgi">
<td>
<hr color="$msgcl1" width=100% align=center>
EOD
#ここまで
	}else{
#レス記事表示
print <<EOD;
[$y2[0]] $y2[2] &gt; $y2[8] <small>($timeword)</small><br>
EOD
	}

}
#******************************************************************************
sub delete{
#記事削除

#入力データチェック
&error("記事番号を指定してください。") if ($chdel eq "") || ($chdel =~/[a-zA-Z]/);
&error("削除キーを入力してください。") if $pass eq "";

#削除
my $flag = 0;
my (@y2,@log);

open (IO,"+<$logfile");
eval{flock(IO,2)};
while (<IO>){
	@y2=split(/<>/,$_);
	if (($flag == 1) && ($y2[1] == 0)){
		$flag = 3;
		}
	if (($_ =~ /^$chdel<>/) && (($y2[6] eq $pass) || ($pass eq $adminpass))){
		if ($y2[1] == 0){
			$flag = 1;
			}else{
			$flag = 2;
			}
		}
	if ($flag == 2){$flag = 4;}
	elsif ($flag == 1){}
	else{push(@log,$_);}
	
	#フラグが2ならばその記事のみ削除。
	#フラグが1ならば、1の間ずっと削除
	}

if ($flag != 0){
	truncate(IO,0);
	seek(IO,0,0);
	print IO @log;
	close (IO);
	if ($flag == 4){
		&error("$chdel番の記事を削除しました。");
		}else{
		&error("$chdel番とそのレス記事を削除しました。");
		}
	}else{
	close (IO);
	&error("削除キーが間違っています。");
	}
}

#******************************************************************************
sub error{
#エラー

&hphead;
print <<EOD;
<br><br>
<table align=center bgcolor=$error1 width=60%>
<tr><td>
<table bgcolor=$error2 width=100%>
<tr><td align=center>

<br><br><br>
<b>$_[0]</b><br>
<br><br><br>

</td></tr>
</table>

</td></tr></table>

<br>
<div align=center>
<a href="./lresbbs.cgi">戻る</a>
</div>
<br><br>
EOD
&hpfoot;
}
#******************************************************************************
sub hphead{
#ヘッダ表示
print "Content-type: text/html; charset=shift_jis\n\n";
print <<EOD;
<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=shift_jis">
<meta http-equiv="pragma" content="no-cache">
<title>$title</title>
$sheet
</head>
$bodytag
$pagetop
EOD
}
#******************************************************************************
sub hpfoot{
#フッタ表示
#
#著作権表示を消すことを禁じます。
print <<EOD;
<br><br>
<div align=center><a href="http://dream.lib.net/room/" target="_blank">Line Response BBS by The Room</a></div>
<br>
</body>
</html>
EOD
exit;
}
#******************************************************************************
