#!/usr/local/bin/perl
require 'jcode.pl';
#--------------------------------------------------------------------
#--------------------------------------------------------------------
$ver = 'freeweBBS ver.1.1';
#
#	freeweb推奨 簡易掲示版
#
#  仕様
#	freewebのサーバーで動作確認をしています。
#	100件まで記事を保存。一度に10件まで表示します。
#	100件を超えて保存した場合、古い記事から削除されます。
#
#  利用条件
#	freewebサーバー内に設置して利用する場合に限り無料で利用できます。
#
#  ご注意
#	このスクリプトは無保証、無サポートです。
#	freeweb 及び TRY-NET へのお問い合わせはご遠慮願います。
#	設置、運営、改造等は個人の責任で行ってさい。
#	バナーの表示部分を変更しないで下さい。
#	改造、無改造に関わらず再配布を一切禁止いたします。
#
#		制作 freeweb 技術スタッフ
#		http://www.freeweb.ne.jp/
#		(C)TRY NETWORK INTERNATIONAL 1999
#--------------------------------------------------------------------
#--------------------------------------------------------------------
#	初期設定（必要に応じて変更してください）
#	HTML部分はスクリプトの末尾にあります。
#	引用符「'」や行末「;」を消さないように注意してください。
#--------------------------------------------------------------------

# 記録ファイル名を指定します
$file = 'skeltonbbs.dat';

# 管理者パスワードを指定します（半角英数）
$passwd = 'IhtMSDyP';

# 掲示板のタイトル名とタイトル文字色を指定します

$title = 'シナリオ・スケルトン &amp; シナリオ・モジュール掲示板';
$color = '#cc6600';

# BODYタグに使う色を指定します

$bgcolor = '#ffffcc';
$text = '#330000';
$link = '#009933';
$vlink = '#009933';
$alink = '#993300';

# 「HOME」のリンク先URL（あなたのホームページ）
$home = 'http://skoba.hp.infoseek.co.jp/';


# 他の場所にあるフォームからの不正投稿を禁止する
# 0:許可 (不正投稿を受けやすくなります)
# 1:禁止（一部のブラウザで不具合が起こります）

$strict = 0;

# プロキシを通した投稿を禁止する
# 0:許可 (デフォルト)
# 1:禁止（一般のプロキシも全て禁止されます）

$proxy = 0;

# スクリプトの文字コードを指定します
# 0:Shift_JIS (デフォルト)
# 1:EUC-JP（スクリプトをEUCで使用したい場合）

$code = 0;

#--------------------------------------------------------------------
#	メイン
#--------------------------------------------------------------------
$bbsurl = "http://$ENV{'HTTP_HOST'}$ENV{'SCRIPT_NAME'}";
@moji = ('Shift_Jis','EUC-JP','sjis','euc');
read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
foreach (split(/&/,$buffer)) {
	my($name, $value) = split(/=/);
	$value =~ tr/+/ /;
	$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	jcode::convert(\$value,$moji[$code+2]);
	$value = rmtag($value);
	if ($name eq 'value'){$value = cvcrlf($value)}else{$value = rmcrlf($value)};
	$FORM{$name} = $value;
}
&view if $FORM{'action'} eq '';
&regist if $FORM{'action'} eq 'regist';
if ($FORM{'passwd'} eq $passwd){
	&admin if $FORM{'action'} eq 'admin';
	&remove if $FORM{'action'} eq 'remove';
}else{
	out('アクセスエラー','パスワードが違います。')
}
exit(1);
sub view {
	open(DB,"$file") || out('ファイル入力エラー','データーファイルのオープンに失敗しました');
		@lines = <DB>;
	close(DB);
	getcookie($file);
	($c_name,$c_email,$c_url) = split(/\t/,$COOKIE{$file});
        $c_url eq "" and $c_url="http://";
	my $start = 0;
	$ENV{'QUERY_STRING'} =~ /start=(\d+)/ and $start = $1;
	my $stop = $start + 9;
	$stop = $#lines if $stop > $#lines;
	&html;
	if ($start <= $stop) {
		print '<Div align=right><Font size="-1">';
		print "<A href=\"$bbsurl?\">最初のページ</A> " unless $start == 0;
		print ''.($start+1).'件〜 '.($stop+1).'件 ';
		print " <A href=\"$bbsurl?start=".($stop+1)."\">次のページ→</A>" unless $stop == $#lines;
		print "</Font></Div>\n";

		foreach (@lines[$start .. $stop]) {
			chomp;
			my($serial,$host,$date,$name,$email,$url,$subject,$value) = split(/"/);
			$name = "<a href=\"mailto:$email\">$name</a>" if $email ne '';
			$url = "\[<a href=\"$url\">URL</a>\]" if $url ne '';
			print "<HR><Font size=+1 color=\"$color\"><B>$subject</B></Font>\n";
			print "<Font size =\"-1\">投稿者</Font> <B>$name</B> <Font size =\"-1\">$url $date</Font><!-- host:$host -->\n";
			print "<BLOCKQUOTE>$value</BLOCKQUOTE>\n";
		}
		print "<HR>\n";
	}else{
		print '記事がありません<HR>';
	}
	&html2;
	exit(0);
}
sub regist {
	out('アクセスエラー','不正投稿だと思われます。') if ($strict ==1 and $ENV{'HTTP_REFERER'} !~ /^$bbsurl/);
	out('アクセスエラー','恐れ入りますが、プロキシからの投稿はお断りしております。') if ($proxy ==1 and defined $ENV{'HTTP_VIA'});
	out('入力エラー','名前が入力されていません。') if $FORM{'name'} eq "";
	out('入力エラー','メールアドレスが異常です。') if ($FORM{'email'} ne "" and $FORM{'email'} !~ /^.+\@.+\..+/);
	out('入力エラー','タイトルが入力されていません。') if $FORM{'subject'} eq "";
	out('入力エラー','本文が入力されていません。') if $FORM{'value'} eq "";
	$FORM{'url'} = "" if $FORM{'url'} eq "http\://";
	out('入力エラー','URLが異常です') if ($FORM{'url'} ne "" and $FORM{'url'} !~ /^http\:\/\/.+/);
	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
	$servertime = sprintf ("%04d年%02d月%02d日 %02d時%02d分",$year+1900,++$mon,$mday,$hour,$min,$sec);
	($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time + 2592000);
	$wday = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday') [$wday];
	$mon = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$mon];
	$cooktime = sprintf ("%s, %s-%s-%04d %02d:%02d:%02d GMT",$wday,$mday,$mon,$year+1900,$hour,$min,$sec);
	$serial = time.$$;
	if (defined $ENV{'HTTP_VIA'}){
		$host = "$ENV{'REMOTE_ADDR'}\[proxy $ENV{'HTTP_VIA'} $ENV{'HTTP_X_FORWARDED_FOR'}\]";
	}else{
		$host = $ENV{'REMOTE_ADDR'};
	}
	my $newline = join('"',($serial,$host,$servertime,$FORM{'name'},$FORM{'email'},$FORM{'url'},$FORM{'subject'},$FORM{'value'}."\n"));
	open(DB,"+<$file") || out('ファイル出力エラー','データファイルの属性を確認してください。');
	flock(DB,2);# lock
		@lines = <DB>;
		if ( unshift(@lines,$newline) > 1000){
			while ($#lines >= 1000){;
				pop(@lines);
			}
		}
		seek(DB,0,0);
		truncate(DB,0);
		print DB @lines;
	close(DB);
	$cook = "$FORM{'name'}\t$FORM{'email'}\t$FORM{'url'}";
	$cook =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
	$cook =~ tr/ /+/;
	print "Set-Cookie: $file=$cook; expires=$cooktime\n";
	print "Location: $bbsurl\?\n\n";
	exit(0);
}
sub admin{
	open(DB,"$file") || out('ファイルエラー','ファイルオープンに失敗しました。');
		@lines = <DB>;
	close(DB);
	print "Pragma: no-cache\n";
	print "Content-type: text/html\n\n";
	print qq{<HTML><HEAD><META http-equiv="Content-Type" content="text/html; charset=$moji[$code]">\n};
	print '<TITLE>管理モード</TITLE></HEAD><BODY>';
	print "<H3>記事の削除</H3>\n";
	print "<FORM action=\"$bbsurl\" method=\"POST\">\n";
	print "チェックした項目を削除します<BR>";
	print "<input type=\"submit\" value=\"削除\"><input type=\"reset\" value=\"リセット\"><BR>\n";
	foreach (@lines) {
		chomp;
		my($serial,$host,$date,$name,$email,$url,$subject,$value) = split(/"/);
		print "<HR><INPUT type=\"checkbox\" name=\"$serial\" value=\"t\"><B>$subject</B>\n";
		print "投稿者 <B>$name</B>$date IPアドレス $host\n";
		print "<BLOCKQUOTE>$value</BLOCKQUOTE>\n";
	}
	print "<HR><input type=\"hidden\" name=\"action\" value=\"remove\">\n";
	print "<input type=\"hidden\" name=\"passwd\" value=\"$FORM{'passwd'}\">\n";
	print "<input type=\"submit\" value=\"削除\"><input type=\"reset\" value=\"リセット\"></FORM>\n";
	print "</BODY></HTML>\n";
	exit;
}
sub remove{
	open(DB,"+<$file") || out('ファイル出力エラー','データファイルの属性を確認してください。');
	flock(DB,2);# lock
		@lines = <DB>;
		foreach (@lines) {$FORM{(split(/"/))[0]} eq "t" || push(@new,$_);}
		seek(DB,0,0);
		truncate(DB,0);
		print DB @new;
	close(DB);
	print "Location: $bbsurl\?\n\n";
	exit(0);
}
sub getcookie{
	my $cookname = shift;
	foreach ( split(/;/,$ENV{'HTTP_COOKIE'})) {
		my($name, $value) = split(/=/);
		$name =~ tr/ //d;
		$COOKIE{$name} = $value;
	}
	$COOKIE{$cookname} =~ tr/+/ /;
	$COOKIE{$cookname} =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	chomp($COOKIE{$cookname});
}
sub rmtag {
	my $value = shift;
	$value =~ s/&/&amp;/g if index($value,'&') != -1;
	$value =~ s/</&lt;/g if index($value,'<') != -1;
	$value =~ s/>/&gt;/g if index($value,'>') != -1;
	$value =~ s/"/&quot;/g if index($value,'"') != -1;
	return $value;
}
sub cvcrlf {
	my $value = shift;
	out('エラー','処理する文字列が長すぎます。') if length($value) >1600;
	$value =~ s/\r\n/<BR>/g if index($value,"\r\n") != -1;
	$value =~ s/\r/<BR>/g if index($value,"\r") != -1;
	$value =~ s/\n/<BR>/g if index($value,"\n") != -1;
	return $value;
}
sub rmcrlf {
	my $value = shift;
	out('エラー','処理する文字列が長すぎます。') if length($value) >80;
	$value =~ tr/\r\n\t//d;
	return $value;
}
sub out {
	my $title = shift;
	my $body = shift;
	print "Content-type: text/html\n\n";
	print qq{<HTML><HEAD><META http-equiv="Content-Type" content="text/html; charset=$moji[$code]">\n};
	print "<TITLE>$title</TITLE></HEAD>\n<BODY><H1>$title</H1><P>$body</P><HR><ADDRESS>$ver<ADDRESS></BODY></HTML>";
	exit(1);
}
#--------------------------------------------------------------------
#--------------------------------------------------------------------
#	ここからHTMLのコードです
#<!-- ■ --> とコメントのある付近ならば好きなタグを追加できます
#--------------------------------------------------------------------
sub html {
#--------HTMLの先頭部分---------
print << "ENDHTML";
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=$moji[$code]">
<META name="robots" content="noindex,nofollow">
<TITLE>$title</TITLE>
</HEAD>
<BODY bgcolor="$bgcolor" text="$text" link="$link" vlink="$vlink" alink="$alink">
<Div align=center><A HREF="http://www.freeweb.ne.jp/cgi-bin/ad/redirect.cgi" target="_top">
<IMG src="http://www.freeweb.ne.jp/cgi-bin/ad/getimage.cgi?REGION=freeweb" width=468 height=60></a></Div>
<HR>
<Div align=center><Font size="+2" color="$color"><B>$title</B></Font></Div>
<A href="$home">HOME</A><BR>
<!-- ■ -->
<!-- ■ -->
<Form method="POST" action="$bbsurl">
<input type="hidden" name="action" value="regist">
お名前 <input type="text" name="name" size=20 value="$c_name" maxlength=19><BR>
メール <input type="text" name="email" size=20 value="$c_email"><BR>
タイトル <input type="text" name="subject" size=40>
<input type="submit" value="    送信    "><input type="reset" value=" リセット "><BR>
メッセージ<font size="-1">（HTMLタグは使用できません）</font><BR>
<textarea name="value" rows=5 cols=70></textarea><BR>
URL <input type="text" name="url" size=30 value="$c_url"><BR>
</Form>
ENDHTML
#-----------ここまで------------
}
sub html2{
#--------HTMLの末尾部分---------
print << "ENDHTML";
<!-- ■ -->
<!-- ■ -->
<Div align=center>
<A href="http://www.freeweb.ne.jp/">$ver</A><BR><BR>
<A HREF="http://www.try-net.or.jp/"><IMG SRC="http://www.freeweb.ne.jp/ad/trynet.gif" width=90 height=34></A>
<A HREF="http://www.freeweb.ne.jp/"><IMG SRC="http://www.freeweb.ne.jp/ad/freeweb_s.gif" width=90 height=34></A>
<BR>
<Font size="-1">
<Form method="POST" action="$bbsurl">
<input type="hidden" name="action" value="admin">
管理者用<input type="password" name="passwd" size=9><input type="submit" value=" 入室 ">
</Form>
</Font>
</Div>
</BODY>
</HTML>
ENDHTML
#-----------ここまで------------
}
#-- END --
