#!/usr/bin/perl

require 'jcode.pl';

# バージョン情報
$version = "Aqua Board Ver 1.05";
#CGI改良(RES上げ機能、文字化け解消設定)
#    * Yossy Town *　http://www.yoshimitsu-jp.com/yoshiko/
# ##############################

# 設定開始 ####


# スクリプトの戻り先
$onscript = "http://www.yosshii.net/jwf/www/sg/sg.cgi";

# データファイル指定
$savefile = "sgdata.dat";

# パスワード設定（必ず複雑なものに変えてください）
$aquapass = "fypdfu";

# タイトル
$title = "我流人";

# 背景色
$bgcolor = "#ff99ff";

# テキスト色
$textcolor = "#000000";

# リンク色
$linkcolor = "#A4DBFF";

# アクティブリンク色
$alinkcolor = "#A4DBFF";

# 既リンク色
$vlinkcolor = "#FFA4F3";

# 投稿用swfファイルの位置と名前
$aquaswf = "sgboard.swf";

# 改ページ用swfファイルの位置と名前
$pageswf = "page.swf";

# 記事表示部swfファイルの位置と名前
$resswf = "res.swf";

# 掲示板に表示させるファイルの位置と名前
$img_pass="";

# リンクのターゲットウインドウ
$target = "_blank";

# 最大記事数
$max = "50";

# 最大表示数
$pagemax = "10";

# ロックするかどうか(yes or no)
$dolock = "yes";

# ロックファイル名
$lockfile = "aqua.lock";

# 変数名（変更しないでください）
$action = "aqua";


# 設定終了 ####

# 時間の設定＆フォーマットを整える
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon = sprintf("%02d", $mon + 1);
$day = sprintf("%02d", $day);
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$date_now = "$year/$mon/$day $hour\:$min";

# 送られたデータを変数に入れる
if ($ENV{'REQUEST_METHOD'} eq "POST") {
	read(STDIN, $QUERY_DATA, $ENV{'CONTENT_LENGTH'});
} else { $formdata = $ENV{'QUERY_STRING'}; }

# デコード
@pairs = split(/&/,$QUERY_DATA);
foreach $pair (@pairs) {
			($name, $value) = split(/=/, $pair);
			$value =~ tr/+/ /;
			$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
			$value =~ s/\n//g;
			if ($name eq "comment") {
				$value =~ s/</&lt;/g;
				$value =~ s/>/&gt;/g;
            }
			$value =~ s/\r\n\n|\r\n|\r|\n/<BR>/g;
			&jcode'convert(*value,'sjis');
			$FORM{$name} = $value;
}

# 条件分岐
if ($FORM{'action'} eq "$action") { &regist; }
elsif ($FORM{'usrdel'} eq "$action") { &usrdel; }
elsif ($FORM{'resmode'} eq "$action") { &resmode; }
else { &html; }

# HTML表示ルーチン
sub html {

# クッキー取得
&getcookie;

# HTML投稿フォーム
print "Content-type: text/html\n\n";
print <<EOF;
<!DOCTYPE HTML PUBLIC -//IETF//DTD HTML//EN>
<html><head>
<meta http-equiv=Content-Type content= text/html; charset=shift-jis>
<title>$title</title>
<style type="text/css">
<!--
.boarder {
	border: 1px solid #ffffff;
}
.text {
	font-family: "ＭＳ Ｐゴシック", "Osaka";
	font-size: 10pt;
	line-height: 13.5pt;
	color: #000000;
}
-->
</style>
</head>
<body bgcolor=$bgcolor text=$textcolor link=$linkcolor alink=$alinkcolor vlink=$vlinkcolor>
<table border=0 align=center><tr><td>
<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
 ID=aqua WIDTH=500 HEIGHT=290>
<PARAM NAME=movie VALUE="$aquaswf">
 <PARAM NAME=FlashVars VALUE="maincgi=$onscript&cname=$cname&cemail=$cemail&cpass=$cpass&chome=$chome&img_pass=$img_pass&">
 <PARAM NAME=bgcolor VALUE=$bgcolor>
 <PARAM NAME=menu VALUE=false>
 <PARAM NAME=quality VALUE=high>
 <EMBED src="$aquaswf"FlashVars="maincgi=$onscript&cname=$cname&cemail=$cemail&cpass=$cpass&chome=$chome&img_pass=$img_pass&" menu=false bgcolor=$bgcolor quality=high WIDTH=500 HEIGHT=290 TYPE="application/x-shockwave-flash">
</OBJECT>
</td></tr></table>
<br><br>
EOF

# データファイルから記事を読みこみます
if (!open(NOTE,"$savefile")) { &error("ファイルを開けません");}
@DATA = <NOTE>;
close(NOTE);

# 記事を回転
@DATA = reverse(@DATA);

# 変数取得
if ($FORM{'page'} eq '') { $page =0; }
else { $page = $FORM{'page'}; }

# 表示記事数計算処理
$logend = @DATA - 1;
$pageend = $page + ($pagemax - 1);

# もし最大表示数より記事が少なかったら・・・
if ($pageend >= $logend) { $pageend = $logend; }

# データを一件一件、手間ひまかけて、じっくりコトコト・・・
foreach ($page .. $pageend) {
($number,$date,$name,$email,$comment,$pass,$home,$sub,$res) = split(/\,/,$DATA[$_ + $flag]);
$comment =~ s/\r/<br>/g;
chomp($res);
if ($res ne '') { $res = '<br><img src="line.gif" width="360" height="1"><br><br>' . "$res"; }
print <<EOF;
<table width=500 border=0 align=center cellpadding=0 cellspacing=0 class=boarder>
<tr>
	<td>
<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
 ID=page WIDTH=500 HEIGHT=90>
<PARAM NAME=movie VALUE="$resswf"> 
 <PARAM NAME=FlashVars VALUE="name=$cname&home=$home&sub=$sub&resno=$number&maincgi=$onscript&myname=$name&email=$email&date=$date&target=$target">
 <PARAM NAME=quality VALUE=high>
 <PARAM NAME=menu VALUE=false>
 <PARAM NAME=bgcolor VALUE=$bgcolor>
 <EMBED src="$resswf" FlashVars="name=$cname&home=$home&sub=$sub&resno=$number&maincgi=$onscript&myname=$name&email=$email&date=$date&target=$target" quality=high bgcolor=$bgcolor menu=false WIDTH=500 HEIGHT=90 TYPE="application/x-shockwave-flash">
</OBJECT></td>
	</tr>
  <tr>
    <td>&nbsp;</td>
  </tr>


<tr>
    <td><table width=360 border=0 align=center cellpadding=0 cellspacing=0 class=text>
      <tr>
        <td>$comment<br>$res</td>
      </tr>
    </table></td>
  </tr>
  <tr>
    <td>&nbsp;</td>
  </tr>
</table>
<br>
EOF
}

print "<table borader=0 align=center><tr><td align=center>\n";
$nextpage = $pageend + 1;
$backpage = $page - $pagemax;

# ページ
print <<EOF;
<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
 ID=page WIDTH=129 HEIGHT=30>
 <PARAM NAME=movie VALUE="$pageswf?end=$logend&maincgi=$onscript&next=$nextpage&back=$backpage">
 <PARAM NAME=quality VALUE=high>
 <PARAM NAME=menu VALUE=false>
 <PARAM NAME=bgcolor VALUE=$bgcolor>
 <EMBED src="$pageswf?end=$logend&maincgi=$onscript&next=$nextpage&back=$backpage" quality=high bgcolor=$bgcolor menu=false WIDTH=129 HEIGHT=30 TYPE="application/x-shockwave-flash">
</OBJECT>
</td></tr><tr><td><br>
<center>
<small><a href="http://www.flashcgi.net/">Flash CGI/$version</a>
<br>
<font color="#999999">CGI improvement</font><a href="http://www.yoshimitsu-jp.com/yoshiko/" TARGET="_blank" >* Yossy Town *</a><br>
	<a href="http://www.xang-style.com/" target="_blank">Design by Xang Style</a>
</small>
</center>
</td></tr></table>
<br>
</body></html>
EOF
exit;
}

# 書き込みルーチン
sub regist {

# フォームチェック
if ($FORM{'name'} eq "") { &error("名前を入力してください"); }
if ($FORM{'comment'} eq "") { &error("コメントを入力してください"); }
if ($FORM{'email'} && $FORM{'email'} !~ /(.*)\@(.*)\.(.*)/) { &error("E-mailアドレスが正しくありません"); }

# 変数に代入
$name  = $FORM{'name'};
$email = $FORM{'email'};
$pass  = $FORM{'pass'};
$home  = $FORM{'home'};
$comment = $FORM{'comment'};
$comment = &autolink($comment);

# データファイルから記事を読みこみます
if (!open(NOTE,"$savefile")) { &error("ファイルを開けません");}
@DATA = <NOTE>;
close(NOTE);

# 記事数
$count = @DATA;

# 二重投稿排除処理
($pnum,$pdate,$pname,$pemail,$pcom,$pd1,$pd2,$pd3,$pd4) = split(/\,/,$DATA[$count-1]);
if ($name eq $pname && $comment eq $pcom) { &error("二重投稿は禁止です"); }

# 記事ナンバー取得
$number = 1;
	for ($i = 0; $i < @DATA; $i++) {
		($thisid) = split(/,/, $DATA[$i]);
		if ($thisid >= $number) {
			$number = $thisid + 1;
		}
	}

# 整列
$value = "$number\,$date_now\,$name\,$email\,$comment\,$pass\,$home\,$FORM{'sub'}\,$FORM{'res'}\n";

# 記事数が最大記事数の1.2倍を超えていれば削除して書き込み
if ($count > ($max * 1.2)) {
	$i = $max - 1;
	@DATA = reverse(@DATA);
	foreach $line (@DATA) {
	push (@DUMMY,$line);
	$i--;
	if ($i < 1) { last; }
	}
	unshift (@DUMMY,$value);
	@DUMMY = reverse(@DUMMY);
	if ($dolock = "yes") { &lock; }		   # ロック処理
	if (!open(NOTE,">$savefile")) { &unlock;&error("ファイルに書き込めません"); }
	print NOTE @DUMMY;
	close(NOTE);
} else {
	if ($dolock = "yes") { &lock; }		   # ロック処理
	if (!open(NOTE,">>$savefile")) { &unlock;&error("ファイルに書き込めません"); }
	print NOTE $value;
	close(NOTE);
}
if (-e $lockfile) { unlink($lockfile); }	  # ロック解除

# クッキを仕込む
&setcookie;

print "Location: $onscript" . '?' . "\n\n";
}

# レス用ルーチン
sub resmode {

	# フォームチェック！
	if ($FORM{'name'} eq "") { &error("名前を入力してください"); }
	if ($FORM{'comment'} eq "") { &error("コメントを入力してください"); }
	$comment = $FORM{'comment'};
	$comment = &autolink($comment);
        $comment =~ s/\r/<br>/g; 
	
	$FORM{'name'} =~ s/</&lt;/g;
	$FORM{'name'} =~ s/>/&gt;/g;
    
	# ファイルを読み込む
	if (!open(NOTE,"$savefile")) { &error("ファイルを開けません");}
	@DATA = <NOTE>;
	close(NOTE);

	foreach $line (@DATA) {
		($number,$date,$name,$email,$maincom,$pass,$home,$sub,$res) = split(/\,/,$line);
		if ($FORM{'resno'} eq $number) { last; }
		$i++;
	}
	
	chomp $DATA[$i];
	
	# レスを追加
	$DATA[$i] = "$DATA[$i]" . "■$FORM{'name'} <font size=1>[$date_now]</font>" .'<br>' ."$comment <br><br> \n";
	push(@DATA,splice(@DATA,$i,1));
		
	# ロック処理
	if ($dolock = "yes") { &lock; }
	
	# 書き込み
	if (!open(NOTE,">$savefile")) { &unlock;&error("ファイルに書き込めません"); }
	print NOTE @DATA;
	close(NOTE);
	
	# ロック解除
	if (-e $lockfile) { unlink($lockfile); }

	# 再表示
	print "Location: $onscript" . '?' . "\n\n";
	
	
}

# 記事削除ルーチン
sub usrdel {
	if ($FORM{'delno'} eq "" || $FORM{'delpas'} eq "") { &error("記事ナンバーか削除パスが入力されてません"); }
	$delno = $FORM{'delno'};
	$delpas = $FORM{'delpas'};
	
	# データファイルから記事を読みこみます
	if (!open(NOTE,"$savefile")) { &error("ファイルを開けません");}
	@DATA = <NOTE>;
	close(NOTE);
	
	# 配列の何番目にあるか調べる
	foreach $line (@DATA) {
		($number,$date,$name,$email,$comment,$pass,$home,$sub,$res) = split(/\,/,$line);
		if ($FORM{'delno'} eq $number) { last; }
		$i++;
	}
	
	# もしすでに無ければ何もせずに終わる
	unless ($i eq @DATA - 1 && $FORM{'delno'} ne $number) {

		# また読み込む
		($number,$date,$name,$email,$comment,$pass,$home,$sub,$res) = split(/\,/,$DATA[$i]);
	
		# パスワードが正しいか管理人のものであれば削除
		if ($delpas eq $aquapass || $delpas eq $pass) {
			splice(@DATA, $i, 1);
		}
		else { &error("パスワードが違います"); }
	
		# ロック
		if ($dolock = "yes") { &lock; }
	
		# 書き込み
		if (!open(NOTE,">$savefile")) { &unlock;&error("ファイルに書き込めません"); }
		print NOTE @DATA;
		close(NOTE);
	
		# ロック解除
		if (-e $lockfile) { unlink($lockfile); }
	}
	
	# ページに戻る
	print "Location: $onscript" . '?' . "\n\n";
}

# オートリンクルーチン
sub autolink {
	local($_) = $_[0];
	$_ =~ s/(https?|ftp|gopher|telnet|whois|news):\/\/([\w|\!\#\$\%\&\'\(\)\=\-\^\`\\\|\@\~\[\{\]\}\;\+\:\*\,\.\?\/]+)/<a href=\"$1:\/\/$2\" target=\"$target\">$1:\/\/$2<\/a>/g;
	$_ =~ s/([\w|\!\#\$\%\'\=\-\^\`\\\|\~\[\{\]\}\+\*\.\?\/]+)\@([\w|\!\#\$\%\'\(\)\=\-\^\`\\\|\~\[\{\]\}\+\*\.\?\/]+)/<a href="mailto:$1\@$2">$1\@$2<\/a>/g;
	$_;
}


# クッキーセットルーチン
sub setcookie {
	@youbi = ("Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat");
	$cyear = $year + 1;
	if ($day > 28) { $day--; }
	$cooktime = "@youbi[$wday], $day-$mon-$cyear $hour:$min:$sec GMT";
	$cook = "name\|$name\,email\|$email\,pass\|$pass\,home\|$home";
	print "Set-Cookie: AQUABOARD=$cook; expires=$cooktime\n";
}

# クッキー取得ルーチン
sub getcookie {
	@cookdata = split(/\;/,$ENV{'HTTP_COOKIE'});
	foreach $cookdata (@cookdata) {
		local($name, $value) = split(/\=/, $cookdata);
		$name =~ s/ //g;
		$FAKE{$name} = $value;
	}
	@cookdata = split(/\,/,$FAKE{'AQUABOARD'});
	foreach $cookdata (@cookdata) {
		local($name, $value) = split(/\|/, $cookdata);
		$COOKIE{$name} = $value;
	}
	$cname  = $COOKIE{'name'};
	$cemail = $COOKIE{'email'};
	$cpass  = $COOKIE{'pass'};
	$chome  = $COOKIE{'home'};
}

# エラー処理ルーチン
sub error {

print "Content-type: text/html\n\n";
print "<html><head><title>$title</title></head>\n";
print "<body bgcolor=$bgcolor text=$textcolor>\n";
print "<p>\n";
print "<center><h2>Error</h2></center>\n";
print "<i> $_[0] </i></hr></center>\n";
print "</body></html>\n";
exit;
}

# ロック処理ルーチン
sub lock {
	local($flag) = 0;
	foreach (1 .. 8) {
		if (-e $lockfile) { sleep(1); }
		else {
			open(LOCK, ">$lockfile");
			close(LOCK);
			$flag = 1;
			last;
		}
	}
	if ($flag == 0) { &error("Lock is Busy!"); }
}

# ロック解除
sub unlock {
	if (-e $lockfile) { unlink($lockfile); }
}
