#!/usr/local/bin/perl

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

#============#
#  設定項目  #
#============#

# コード変換ライブラリ取込
require './jcode.pl';

# タイトル名
$title = "ウェルネスコラム";

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

# タイトルのサイズ
$t_size  = '18pt';

# 壁紙 (http://から指定）
$bg = "";

# 背景色
#$bc = "#5F6761";
$bc = "#F0F4FF";
# 文字色
#$tx = "#FFFFFF";
$tx = "#000000";

# リンク色
#$lk = "#FFFF80";	# 未訪問
#$vl = "#FFFF80";	# 訪問済
#$al = "#CC0000";	# 訪問中
$lk = "#009999";
#vl = "#009999";
$al = "CC0000";

# 管理用パスワード(英数字)
$pass = '631001';

# 戻り先 (index.htmlなど)
$home = "../index1.html";

# 記事の最大保持数
$max = 40;

# 表示ファイル第1ページの記事数
$pagelog = 10;

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

# CGIスクリプト自身をURLで指定
$script = './sunbbs.cgi';

# 表示ファイル(index.html)のあるディレクトリをURLで指定
#  → 最後は / で閉じる
$htm_url = 'http://www.pmai.jp/';

# 表示ファイル(index.html)のあるディレクトリをサーバパスで指定
#  → 最後は / で閉じる
#  → フルパスなら / から始まるパス（http://からではない）
$htm_dir = './';

# 新着情報ボードモード (0=no 1=yes)
#  → 書き込みは管理者限定となります
$whatsnew = 1;

# 題名部の色
#$obi_color = "#404040";
$obi_color = "#00cccc";
# 題名部ポインタ
$point  = '■';

# 戻り先部ポインタ
$point2 = '▲';

# ポインタの色
#$p_color = "#FFCC33";
$p_color = "#009999";

# 題名の色
#$s_color = "#FFFFFF";
$s_color = "##000099";

# タイトルGIF画像 (http://から記述)
$t_gif = "http://www.pmai.jp/sunbbs/logo.gif";

# タイトル画像の大きさ
$tg_w = '362';	# 横幅
$tg_h = '35';	# 高さ

# ログファイル名
#  → フルパスなら / から記述（http://からではない）
$logfile = './sunbbs.log';

# 表示ファイルHTML (第1ページ)
#  → ファイル名のみを記述
$htmfile = "index.html";

# 表示ファイルHTML (第2ページ)
#  → ファイル名のみを記述
$nexthtm = "index2.html";

# 掲示板使用時のタグ許可 (0=no 1=yes)
$tagkey = 0;

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

# ロックファイル処理
#   0 : なし
#   1 : あり（symlink関数）
#   2 : あり（mkdir関数）
$lockkey = 0;

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

# ブラウザのキャッシュ取込を拒否 (0=no 1=yes)
$nocashe = 1;

# 投稿後に内容確認画面を表示 (0=no 1=yes)
#  → 投稿後自動的に表示画面に戻らない場合は「1」とすること
$msg_check = 1;

# 投稿があるとメール通知する (0=no 1=yes)
$mailing = 1;

# メールアドレス(メール通知する時)
$mailto = 'harada@asnt.co.jp';

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

## --- 管理者コメント（タイトル下部にちょっとしたコメントを表示できます）
$message = <<"MSG";
個人別の健康管理方法を分析、提案するパートナーとして。
\予\防医学分析研究所　若狭良成
MSG

#---(以下は「過去ログ」機能を使用する場合の設定です)---#
#
# 過去ログ生成 (0=no 1=yes)
$pastkey = 1;

# 過去ログ用NOファイル
$nofile  = './pastno.dat';

# 過去ログのディレクトリ
# → フルパスなら / から記述（http://からではない）
# → 最後は必ず / で閉じる
$pastdir = './past/';

# 過去ログ１ファイルの行数
# → この行数を超えると次ページを自動生成します
$log_line = 600;

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

&decode;
if ($mode eq 'regist') { &regist; }
elsif ($mode eq 'form') { &form; }
elsif ($mode eq 'find') { &find; }
elsif ($mode eq 'admin') { &admin; }
elsif ($mode eq 'mente') { &mente; }
elsif ($mode eq 'edit') { &edit; }
elsif ($mode eq 'userdel') { &userdel; }
elsif ($mode eq "past" && $pastkey) { &past; }
elsif ($mode eq "check") { &check; }
&location;


#----------------#
#  投稿フォーム  #
#----------------#
sub form {
	# フォームサイズを定義
	&form_size;

	print &header;
	print "[<a href=\"javascript:history.back()\">戻る</a>]\n";
	print "<blockquote><form action=\"$script\" method=\"$method\">\n";
	print "<input type=hidden name=mode value=\"regist\">\n";
	print "<input type=hidden name=pass value=\"$in{'pass'}\">\n";

	# 掲示板モードのとき
	if (!$whatsnew) {
	  	&get_cookie;

	  ## 返信の場合
	  if ($in{'no'}) {
		# ログを開く
		open(IN,"$logfile") || &error("Can't open $logfile");
		while (<IN>) {
			($num,$date,$name,$email,$sub,$com) = split(/<>/);
			if ($in{'no'} == $num) { last; }
		}
		close(IN);

		# 返信用項目を作成
		if ($sub =~ /^Re/) {
			$sub =~ s/Re//;
			$res_sub = "Re\[$num\]" . "$sub";
		} else {
			$res_sub = "Re\[$num\]\: $sub";
		}
		$res_com = "&gt; $com";
		$res_com =~ s/<br>/\r&gt; /ig;
	  }
	  print "<table><tr><td nowrap><b>おなまえ</b>\n";
	  print "<td><input type=text name=name size=\"$nam_wid\" value=\"$ck{'name'}\">\n";
	  print "<tr><td nowrap><b>Ｅメール</b>\n";
	  print "<td><input type=text name=email size=\"$nam_wid\" value=\"$ck{'email'}\">\n";
	}
	# 新着ボードモードのとき
	else {
		$date = &get_time;
	    	print "以下のフォームから記事を投稿して下さい。<P>\n";
	    	print "<table><tr><td nowrap><b>日　付</b>\n";
	    	print "<td><input type=text name=date value=\"$date\" size=20>\n";
	}
	print "<tr><td nowrap><b>タイトル</b>\n";
	print "<td><input type=text name=sub size=\"$sub_wid\" value=\"$res_sub\">\n";
	print "<input type=submit value='投稿する'><input type=reset value='リセット'>\n";
	print "<tr><td colspan=2><b>コメント</b><br>\n";
	print "<textarea name=comment cols=\"$com_wid\" rows=6 wrap=soft>$res_com</textarea>\n";
	print "<tr><td nowrap><b>ＵＲＬ</b>\n";
	print "<td><input type=text name=url size=$url_wid value=\"http://$ck{'url'}\">\n";

	if (!$whatsnew) {
	  	print "<tr><td nowrap><b>削除キー</b>\n";
	  	print "<td><input type=password name=pwd size=8 maxlength=8 value=\"$ck{'pwd'}\">\n";
	  	print "記事を削除時に使用 (英数字で8文字以内)\n";
	}

	print "</table></form></blockquote><hr>\n";
	if ($in{'page'} == 2) {
		$next = $pagelog+1;
		$last = $max;
	} else {
		$next = 0;
		$last = $pagelog;
	}
	open(IN,"$logfile") || &error("Open Error : $logfile");
	$i=0;
	while ($data = <IN>) {
		$i++;
		if ($i < $next) { next; }
		if ($i > $last) { last; }
		print &log_view($data, $in{'page'});
	}
	close(IN);
	print "</body>\n</html>\n";
	exit;
}

#------------#
#  投稿処理  #
#------------#
sub regist {
	# パスワードチェック
	if ($whatsnew && $in{'pass'} ne $pass) { &error("パスワードが違います"); }
	if (!$whatsnew && $in{'name'} eq "") { &error("なまえの記入がありません"); }
	if ($in{'comment'} eq "") { &error("コメントに記入がありません"); }

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

	open(IN,"$logfile") || &error("Open Error : $logfile");
	@lines = <IN>;
	close(IN);

	# 二重投稿の禁止
	($num,$date,$name,$email,$sub,$com) = split(/<>/, $lines[0]);
	&error("二重投稿は禁止です") if ($in{'name'} eq $name && $in{'comment'} eq $com);

	# クッキーを発行
	if (!$whatsnew) { &set_cookie; }

	# 記事Noカウント
	$no = $num + 1;

	# 削除キーを暗号化
	if ($in{'pwd'} ne "") { $pw = &encrypt($in{'pwd'}); }

	# ホスト名取得
	$host = &get_host;

	# 日付処理
	if ($whatsnew) { $date = $in{'date'}; } else { $date = &get_time; }

	# ログを更新
	while ($max <= @lines) {
		local($log) = pop(@lines);
		unshift(@data,$log) if ($pastkey);
	}
	&pastlog if ($pastkey);
	unshift (@lines,"$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pw<>\n");
	open(OUT,">$logfile") || &error("Write Error : $logfile");
	print OUT @lines;
	close(OUT);

	# HTMLファイルを生成
	&html_regist("$htm_dir$htmfile","1");
	&html_regist("$htm_dir$nexthtm","2") if ($pagelog < @lines);

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

	# メール通知処理
	if ($mailing && $in{'email'} ne $mailto) { &mail_to; }

	# HTMLファイルへ戻る
	&location;
	exit;
}

#----------------#
#  HTML生成処理  #
#----------------#
sub html_regist {
	local($file, $page) = @_;

	open(WR,">$file") || &error("Write Error : $file");
	print WR &header('HTML');

	# リンク部
	print WR "<B><font color=\"$p_color\">$point2</font>";
	print WR "<a href=\"$home\" target=\"_top\">Home</a>\n";

	if (!$whatsnew) {
	  	print WR "<font color=\"$p_color\">$point</font>";
		print WR "<a href=\"$script?mode=form\">Post</a>\n";
	}

	print WR "<font color=\"$p_color\">$point</font>";
	print WR "<a href=\"$script?mode=find\">Search</a>\n";

	# 過去ログ
	if ($pastkey) {
		print WR "<font color=\"$p_color\">$point</font>";
		print WR "<a href=\"$script?mode=past\">Log</a>\n";
	}

	print WR "<font color=\"$p_color\">$point</font>";
	print WR "<a href=\"$script?mode=admin\">Admin</a></B>\n<div align=center>\n";

	# タイトル部
	if ($t_gif eq '') {
	  	print WR "<font color=\"$t_color\" size=6><b style=\"font-size:$t_size\">$title</b></font>\n";
	} else {
	  	print WR "<img src=\"$t_gif\" width=$tg_w height=$tg_h alt=\"$title\">\n";
	}

	# ひとことメッセージを表示
	$message =~ s/\r\n/<br>/g;
	$message =~ s/\r/<br>/g;
	$message =~ s/\n/<br>/g;

	print WR "<P>$message</div><hr>\n";

	# 記事を展開
	if ($page == 2) {
		$next = $pagelog+1;
		$last = $max;
	} else {
		$next = 0;
		$last = $pagelog;
	}
	open(IN,"$logfile") || &error("Open Error : $logfile");
	$i=0;
	while ($data = <IN>) {
		$i++;
		if ($i < $next) { next; }
		if ($i > $last) { last; }
		print WR &log_view($data, $page);
	}
	close(IN);
	if (!$whatsnew) { print WR "<table align=left><tr>\n"; }

	# 次／前ページのリンクを生成
	if (@lines > $pagelog && $page == 1) {
	  	print WR "<td><form action=\"$htm_url$nexthtm\">";
	  	print WR "<input type=submit value=\"次ページ\"></td></form>\n";
	} elsif (@lines > $pagelog && $page == 2) {
	  	print WR "<td><form action=\"$htm_url$htmfile\">";
	  	print WR "<input type=submit value=\"前ページ\"></Td></form>\n";
	}
	print WR "</table>\n";

	# 削除フォーム
	if (!$whatsnew) {
	  	print WR "<table align=right><tr><td>\n";
	  	print WR "<form action=\"$script\" method=\"$method\">\n";
	  	print WR "記事No <input type=text name=no size=4>\n";
	  	print WR "削除キー <input type=password name=pwd size=4>\n";
	  	print WR "<input type=hidden name=mode value=userdel>\n";
	  	print WR "<input type=submit value='記事削除'></td></form></table><br clear=all>\n";
	}

	# 著作権を表示（削除禁止）
	print WR "<div align=center style='font-size:9pt'><!-- $ver -->\n";
	print WR "- <a href='http://www.kent-web.com/' target='_top'>Sun Board</a> -\n";
	print WR "</div>\n</body>\n</html>\n";
	close(WR);
}

#--------------------------#
#  表示ファイルにジャンプ  #
#--------------------------#
sub location {
	# 投稿確認画面の表示
	if ($msg_check) {
		print &header;
		print "<br><br><div align=center>\n";
		print "<h3>処理は正常に完了しました</h3>\n";
		print "<form action=\"$htm_url$htmfile\">\n";
		print "<input type=submit value='閲覧画面に戻る'></form>\n";
		print "</div>\n</body>\n</html>\n";
		exit;
	}

	# IISサーバ対応
	if ($ENV{PERLXS} eq "PerlIS") {
		print "HTTP/1.0 302 Temporary Redirection\r\n";
		print "Content-type: text/html\n";
	}
	print "Location: $htm_url$htmfile\n\n";
}

#------------------#
#  管理用初期画面  #
#------------------#
sub admin {
	# ログイン画面
	if ($in{'pass'} eq '') {
		print &header;
		print "<table width='100%'><tr><th bgcolor=\"$obi_color\">\n";
		print "<font color=\"$s_color\">入室画面</font></table>\n";
		print "<div align=center><h4>管理用パスワードを入力して下さい</h4>\n";
		print "<form action=\"$script\" method=\"$method\">\n";
		if ($whatsnew) {
		    print "<input type=radio name=mode value=form checked>書込\n";
		    print "<input type=radio name=mode value=admin>ログ<P>\n";
		} else {
		    print "<input type=hidden name=mode value=admin>\n";
		}
		print "<input type=password name=pass size=8>\n";
		print "<input type=submit value=' 認証 '></form></div>\n";
		print "</body>\n</html>\n";
		exit;
	}

	# 修正
	if ($in{'ope'} eq 'mente' && $in{'no'}) { &mente; }

	# パスワードチェック
	if ($in{'pass'} ne $pass) { &error("パスワードが違います"); }

	# 削除
	elsif ($in{'ope'} eq 'del' && $in{'no'}) {
		if ($lockkey) { &lock; }
		@lines=();
		$i=0;
		open(IN,"$logfile") || &error("Open Error : $logfile");
		while (<IN>) {
			$i++;
			($no) = split(/<>/);
			if ($in{'no'} == $no) { $i2=$i; next; }
			push(@lines,$_);
		}
		close(IN);
		open(OUT,">$logfile") || &error("Write Error : $logfile");
		print OUT @lines;
		close(OUT);

		if ($i2 > $pagelog) { &html_regist("$nexthtm", "2"); }
		elsif ($i2 <= $pagelog) {
			&html_regist("$htm_dir$htmfile", "1");
			&html_regist("$htm_dir$nexthtm", "2") if ($pagelog < @lines);
		}
		if ($lockkey) { &unlock; }
	}

	# 管理画面
	print &header;
	print <<"EOM";
[<a href="$htm_url$htmfile">戻る</a>]
<table width="100%"><tr><th bgcolor="$obi_color">
<font color="$s_color">管理画面</font></table>
<form action="$script" method="$method">
<input type=hidden name=mode value="admin">
<input type=hidden name=pass value="$in{'pass'}">
<input type=submit value=" 選択する ">
<select name=ope>
<option value=mente>修正
<option value=del>削除</select>
<DL>
EOM
	# ログ表示
	open(IN,"$logfile") || &error("Open Error : $logfile");
	while (<IN>) {
		($no,$date,$name,$email,$sub,$com,$url,$host) = split(/<>/);
		$name="<a href=\"mailto:$email\">$name</a>" if ($email);
		$url="&lt;<a href=\"http://$url\">URL</a>&gt;" if ($url);
		$com =~ s/<br>//g; $com =~ s/</&lt;/g; $com =~ s/>/&gt;/g;
		if (length($com) > 60) { $com=substr($com,0,58); $com .= "..."; }

		print "<DT><hr><input type=radio name=no value=\"$no\">\n";
		print "[<b>$no</b>] <b>$sub</b> - $name $url\n";
		print "<DD>$date ($host)\n<DD>$com\n";
	}
	close(IN);
	print "<DT><hr>\n</DL>\n</form>\n</body>\n</html>\n";
	exit;
}

#----------------#
#  記事編集処理  #
#----------------#
sub mente {
	if ($in{'pass'} ne $pass) { &error("パスワードが違います"); }

	if ($in{'num'}) {
		if ($lockkey) { &lock; }
		@lines=();
		$i=0;
		open(IN,"$logfile") || &error("Open Error : $logfile");
		while (<IN>) {
			$i++;
			($no,$date,$name,$email,$sub,$com,$url,$host,$pwd) = split(/<>/);
			if ($in{'num'} == $no) {
				$i2=$i;
				$_ = "$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pwd<>\n";
			}
			push(@lines,$_);
		}
		close(IN);
		open(OUT,">$logfile") || &error("Write Error : $logfile");
		print OUT @lines;
		close(OUT);

		if ($i2 <= $pagelog) { &html_regist("$htm_dir$htmfile", "1"); }
		elsif ($i2 > $pagelog) { &html_regist("$htm_dir$nexthtm", "2"); }
		if ($lockkey) { &unlock; }
		&admin;
	}

	print &header;
	print <<"EOM";
[<a href="$htm_url$htmfile">戻る</a>]
<table width="100%"><tr><th bgcolor="$obi_color">
<font color="$s_color">管理画面</font></table>
<form action="$script" method="$method">
<input type=hidden name=pass value="$in{'pass'}">
<input type=hidden name=mode value="mente">
<input type=hidden name=num value="$in{'no'}">
<table>
EOM
	open(IN,"$logfile") || &error("Open Error : $logfile");
	while (<IN>) {
		($no,$date,$name,$email,$sub,$com,$url) = split(/<>/);
		last if ($in{'no'} == $no);
	}
	close(IN);
	$com =~ s/<br>/\r/g;

	if (!$whatsnew) {
	  	print "<tr><td nowrap><b>おなまえ</b>";
	  	print "<td><input type=text name=name size=25 value=\"$name\">\n";
	  	print "<tr><td nowrap><b>E-mail</b>";
	  	print "<td><input type=text name=email size=25 value=\"$email\">\n";
	}
	print "<tr><td nowrap><b>タイトル</b>";
	print "<td><input type=text name=sub size=35 value=\"$sub\">\n";
	print "<input type=submit value='編集する'>";
	print "<input type=reset value='リセット'>\n";
	print "<tr><td colspan=2><b>コメント</b><br>\n";
	print "<textarea name=comment cols=55 rows=6 wrap=soft>$com</textarea>\n";
	print "<tr><td nowrap><b>URL</b>";
	print "<td><input type=text name=url size=60 value=\"http://$url\">\n";
	print "</table></form>\n</body>\n</html>\n";
	exit;
}

#----------------#
#  記事削除処理  #
#----------------#
sub userdel {
	# フォームチェック
	if ($in{'no'} eq "") { &error("記事NOが入力されていません"); }
	if ($in{'pwd'} eq "") { &error("削除キーが入力されていません"); }

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

	# ログファイルを開く
	@lines=();
	$flag=0;
	$i=0;
	open(IN,"$logfile") || &error("Open Error : $logfile");
	while (<IN>) {
		$i++;
		($num,$date,$name,$email,$sub,$com,$url,$host,$pwd) = split(/<>/);
		if ($in{'no'} == $num) {
			$i2=$i;
			$flag=1;
			if ($pwd eq '') { $flag=2; last; }
			else { $pwd2=$pwd; next; }
		}
		push(@lines,$_);
	}
	close(IN);
	if ($flag == 0) { &error("該当の記事NOが見当たりません"); }
	if ($flag == 2) { &error("削除キーが設定されていません"); }

	# 削除キー照合
	$check = &decrypt($in{'pwd'}, $pwd2);
	if ($check ne 'yes') { &error("削除キーが違います"); }

	# ログを更新
	open(OUT,">$logfile") || &error("Can't write $logfile");
	print OUT @lines;
	close(OUT);

	# HTMLファイルを生成
	if ($i2 > $pagelog) { &html_regist("$nexthtm", "2"); }
	elsif ($i2 <= $pagelog) {
		&html_regist("$htm_dir$htmfile", "1");
		&html_regist("$htm_dir$nexthtm", "2") if ($pagelog < @lines);
	}

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

	# 初期画面に戻る
	&location;
	exit;
}

#----------------#
#  デコード処理  #
#----------------#
sub decode {
	local($buf, @in, $key, $val);
	if ($ENV{'REQUEST_METHOD'} eq "POST") {
		&error("投稿量が大きすぎます") if ($ENV{'CONTENT_LENGTH'} > 51200);
		read(STDIN, $buf, $ENV{'CONTENT_LENGTH'});
	} else { $buf = $ENV{'QUERY_STRING'}; }
	@in = split(/&/, $buf);
	foreach (@in) {
		($key, $val) = split(/=/);
		$val =~ tr/+/ /;
		$val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

		# 文字コード変換
		&jcode'convert(*val,'sjis');

		# タグ処理
		$val =~ s/\0//g;
		if (!$whatsnew && !$tagkey) {
			$val =~ s/</&lt;/g;
			$val =~ s/>/&gt;/g;
		} else {
			$val =~ s/<!--(.|\n)*-->//g;
			$val =~ s/<>/&lt;&gt;/g;
		}
		# 改行処理
		if ($key eq "comment") {
			$val =~ s/\r\n/<br>/g;
			$val =~ s/\r/<br>/g;
			$val =~ s/\n/<br>/g;
		} else {
			$val =~ s/\r//g;
			$val =~ s/\n//g;
		}
		$in{$key} = $val;
	}
	$in{'url'} =~ s/^http\:\/\///;
	$mode = $in{'mode'};
	if ($in{'sub'} eq "") { $in{'sub'} = "無題"; }
}

#--------------#
#  エラー処理  #
#--------------#
sub error {
	&unlock if ($lockflag);
	print &header;
	print "<div align=center><hr width=400><h3>ERROR !</h3>\n";
	print "<font color=\"$t_color\"><B>$_[0]</B></font>\n";
	print "<P><hr width=400></div>\n</body>\n</html>\n";
	exit;
}

#------------------#
#  クッキーの発行  #
#------------------#
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'}";
	print "Set-Cookie: SunBoard=$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{'SunBoard'});
}

#--------------#
#  ワード検索  #
#--------------#
sub find {
	print &header;
	print <<"EOM";
[<a href="$htm_url$htmfile">戻る</a>]
<table width="100%"><tr><th bgcolor="$obi_color">
<font color="$s_color">ワード検索</font></table>
<UL>
<LI>検索したい<b>キーワード</b>を入力し検索条件を選択し「検索」を押してください。
<LI>複数のキーワードを入力するときは、<b>半角スペース</b>で区切って下さい。
<form action="$script" method="$method">
<input type=hidden name=mode value="find">
キーワード <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<input type=submit value=' 検索 '></form>\n</UL>\n";

	# ワード検索の実行と結果表示
	if ($in{'word'} ne '') {
		$in{'word'} =~ s/　/ /g;
		@pairs = split(/\s+/, $in{'word'});

		@new=();
		open(IN,"$logfile") || &error("Can't open $logfile");
		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>件<hr>\n";
		foreach (@new) {
			($no,$date,$name,$email,$sub,$com,$url) = split(/<>/);
		  	$name="<a href=\"mailto:$email\">$name</a>" if ($email);
		  	$url="&lt;<a href=\"http://$url\" target=\"_top\">URL</a>&gt;" if ($url);

		  	print "[<b>$no</b>] <b>$sub</b> 投稿者：<b>$name</b> ";
			print "投稿日：$date $url<blockquote>$com</blockquote><hr>\n";
		}
	}
	print "</body>\n</html>\n";
	exit;
}

#-------------------#
# フォーム幅を定義  #
#-------------------#
sub form_size {
	# ブラウザ情報を取得
	$agent = $ENV{'HTTP_USER_AGENT'};

	# MSIE 3 の場合
	if ($agent =~ /MSIE 3/i) {
		$nam_wid = 30;
		$sub_wid = 40;
		$com_wid = 65;
		$url_wid = 48;
	}
	# MSIE 4/5 の場合
	elsif ($agent =~ /MSIE [4|5]/i) {
		$nam_wid = 30;
		$sub_wid = 40;
		$com_wid = 65;
		$url_wid = 78;
	}
	# その他
	else {
		$nam_wid = 20;
		$sub_wid = 25;
		$com_wid = 56;
		$url_wid = 50;
	}
}

#------------------#
#  HTMLのヘッダー  #
#------------------#
sub header {
	local($_);
	return if ($headflag);
	if ($_[0] ne 'HTML') {
		$_ .= "Content-type: text/html\n\n";
		$headflag=1;
	}
	$_ .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
	$_ .= "<html lang=\"ja\"><head>\n";
	$_ .= "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">\n" if ($nocashe);
	$_ .= "<META HTTP-EQUIV=\"Content-type\" CONTENT=\"text/html; charset=Shift_JIS\">\n";
	$_ .= "<META HTTP-EQUIV=\"Content-Style-Type\" content=\"text/css\">\n";
	$_ .= "<STYLE type=\"text/css\"><!--\n";
	$_ .= "body,tr,td,th { font-size:10pt; font-family:'MS UI Gothic'; }\n";
	$_ .= "a:link    { text-decoration:none; }\n";
	$_ .= "a:visited { text-decoration:none; }\n";
	$_ .= "a:active  { text-decoration:none; }\n";
	$_ .= "a:hover { text-decoration:underline; color:$al; }\n--></STYLE>\n";
	$_ .= "<title>$title</title></head>\n";
	if ($bg) {
		$_ .= "<body background=\"$bg\" bgcolor=\"$bc\" text=\"$tx\" link=\"$lk\" vlink=\"$vl\" alink=\"$al\">\n";
	} else {
		$_ .= "<body bgcolor=\"$bc\" text=\"$tx\" link=\"$lk\" vlink=\"$vl\" alink=\"$al\">\n";
	}
	$_;
}

#----------------------#
#  パスワード暗号処理  #
#----------------------#
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);
	$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"; }
	$check;
}

#--------------#
#  ロック処理  #
#--------------#
sub lock {
	if (-e $lockfile) {
		local($mtime) = (stat($lockfile))[9];
		if ($mtime < time - 60) { &unlock; }
	}
	local($retry) = 5;
	# 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 get_host {
	$host = $ENV{'REMOTE_HOST'};
	$addr = $ENV{'REMOTE_ADDR'};
	if ($host eq "" || $host eq $addr) {
		$host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2) || $addr;
	}
	$host;
}

#--------------#
#  時間を取得  #
#--------------#
sub get_time {
	local($date);

	$ENV{'TZ'} = "JST-9";
	($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time);
	@week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');

	# 日時のフォーマット
	if ($whatsnew) {
		$date = sprintf("%04d-%02d-%02d (%s)",
				$year+1900,$mon+1,$mday,$week[$wday]);
	} else {
		$date = sprintf("%04d/%02d/%02d(%s) %02d:%02d",
				$year+1900,$mon+1,$mday,$week[$wday],$hour,$min);
	}
	$date;
}

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

#--------------#
#  メール送信  #
#--------------#
sub mail_to {
	local($mail_sub, $mail_body, $com);

	# メールタイトルを定義
	$mail_sub = "[$title : $no] $in{'sub'}";

	$com = $in{'comment'};
	$com =~ s/<br>/\n/ig;
	$com =~ s/&lt;/</g;
	$com =~ s/&gt;/>/g;

	# メール本文を定義
	$mail_body = <<"EOM";
投稿日時：$date
ホスト名：$host
ブラウザ：$ENV{'HTTP_USER_AGENT'}

おなまえ：$in{'name'}
Ｅメール：$in{'email'}
タイトル：$in{'sub'}
ＵＲＬ  ：http://$in{'url'}
コメント：

$com
EOM

	# JISコード変換
    	&jcode'convert(*mail_sub,'jis');
    	&jcode'convert(*mail_body,'jis');

	# sendmail起動
	if ($in{'email'} eq "") { $in{'email'} = 'nomail@xxx.xxx'; }
	open(MAIL,"| $sendmail -t");
	print MAIL "To: $mailto\n";
	print MAIL "From: $in{'email'}\n";
	print MAIL "Subject: $mail_sub\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 $mail_body;
	close(MAIL);
}

#------------#
#  ログ表示  #
#------------#
sub log_view {
	local($_);
	local($data, $page) = @_;
	($num,$date,$name,$email,$sub,$com,$url,$host) = split(/<>/, $data);
	&auto_link($com) if ($autolink);

	# 掲示板モードの場合
	if (!$whatsnew) {
		$_ .= "<table width='100%' cellpadding=2><tr>\n";
		$_ .= "<td bgcolor=\"$obi_color\">　<font color=\"$p_color\">$point</font>\n";
		$_ .= "<font color=\"$s_color\"><b>$sub</b></font></table>\n";
		$_ .= "<table cellspacing=0 cellpadding=1>\n";
		$_ .= "<tr><td width=15><td>No.<td>： <B>$num</B> [<a href=\"$script?mode=form&no=$num&page=$page\">返信</a>]\n";
		$_ .= "<tr><td width=15><td>Name<td>： <b>$name</b>\n";
# 2002-11-20 日付削除
#		$_ .= "<tr><td width=15><td>Date<td>： $date\n";
		$_ .= "<tr><td width=15><td>Mail<td>： <a href=\"mailto:$email\">$email</a>\n" if ($email);
		$_ .= "<tr><td width=15><td>URL<td>： <a href=\"http://$url\" target=\"_top\">http://$url</a>\n" if ($url);
		$_ .= "</table>\n<blockquote>$com</blockquote><hr>\n";
	}
	# 新着ボードの場合
	else {
		$_ .= "<table width='100%' cellpadding=2><tr>\n";
		$_ .= "<td bgcolor=\"$obi_color\">　<font color=\"$p_color\">$point</font>\n";
		$_ .= "<font color=\"$s_color\"><b>$sub</b></font></table>\n";
#		$_ .= "<table><tr><td width=15><td>Date: $date</table>\n";
		$_ .= "<table><tr><td width=15><td>　</table>\n";
		$_ .= "<blockquote>$com\n";
		$_ .= "<P><a href=\"http://$url\" target=\"_top\">http://$url</a>\n" if ($url);
		$_ .= "</blockquote><hr>\n";
	}
	$_;
}

#----------------#
#  過去ログ生成  #
#----------------#
sub pastlog {
	local($count,$pastfile,@temp);
	local($past_flag)=0;

	# 過去NOを開く
	open(NO,"$nofile") || &error("Open Error : $nofile");
	$count = <NO>;
	close(NO);
	$count = sprintf("%04d", $count);

	# 過去ログのファイル名を定義
	$pastfile = "$pastdir$count\.dat";

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

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

		# カウントファイル更新
		$count++;
		open(NO,">$nofile") || &error("Write Error : $nofile");
		print NO $count;
		close(NO);
		$pastfile = "$pastdir$count\.dat";
		@past=();
	}

	@temp=();
	foreach (@data) {
		local($pno,$pdate,$pname,$pmail,$psub,$pcom,$purl,$pho) = split(/<>/);
		if ($pmail) { $pname = "<a href=\"mailto:$pmail\">$pname</a>"; }
		if ($purl) { $purl = "&lt;<a href=\"http://$purl\" target='_top'>URL</a>&gt;"; }
		push(@temp,"<hr>[<b>$pno</b>] <b>$psub</b> 投稿者：<b>$pname</b> 投稿日：$pdate $purl<br><blockquote>$pcom</blockquote><!-- $pho -->\n");
	}

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

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

#------------#
#  過去ログ  #
#------------#
sub past {
	local($pastno,$next,$back,@new,$count,@wd,$wd);

	open(IN,"$nofile") || &error("Open Error : $nofile");
	$pastno = <IN>;
	close(IN);
	if (!$in{'pastlog'}) { $in{'pastlog'} = $pastno; }
	$in{'pastlog'} = sprintf("%04d", $in{'pastlog'});

	print &header;
	print <<"EOM";
[<a href="$htm_url$htmfile">戻る</a>]
<table width="100%"><tr><th bgcolor="$obi_color">
<font color="$s_color">過去ログ[$in{'pastlog'}]</font></table>
<P><table><tr><td>
<form action="$script" method="$method">
<input type=hidden name=mode value=past>
過去ログ：<select name=pastlog>
EOM
	$pastkey = $pastno;
	while ($pastkey > 0) {
		$pastkey = sprintf("%04d", $pastkey);
		if ($in{'pastlog'} == $pastkey) {
			print "<option value=\"$pastkey\" selected>$pastkey\n";
		} else {
			print "<option value=\"$pastkey\">$pastkey\n";
		}
		$pastkey--;
	}
	print "</select>\n<input type=submit value='移動'></td></form>\n";
	print "<td width=30><td><form action=\"$script\" method=\"$method\">\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 表\示：<select name=view>\n";
	if ($in{'view'} eq "") { $in{'view'} = $pagelog; }
	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></table>\n";

	# 表示ログを定義
	$in{'pastlog'} =~ s/\D//g;
	$file = "$pastdir$in{'pastlog'}\.dat";

	# ワード検索処理
	if ($in{'word'} ne "") {
		$in{'word'} =~ s/　/ /g;
		@wd = split(/\s+/, $in{'word'});

		@new=();
		open(IN,"$file") || &error("Open Error : $file");
		while (<IN>) {
			$flag=0;
			foreach $wd (@wd) {
				if (index($_,$wd) >= 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 "<P>検索結果：<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; }

		$next = $page_end + 1;
		$back = $in{'page'} - $in{'view'};

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

		# 表示開始
		foreach ($in{'page'} .. $page_end) { print $new[$_]; }
		print "<hr>\n</body>\n</html>\n";
		exit;
	}

	# ページ区切り処理
	$start = $in{'page'} + 1;
	$end   = $in{'page'} + $pagelog;

	$i=0;
	open(IN,"$file") || &error("Open Error : $file");
	while (<IN>) {
		$i++;
		if ($i < $start) { next; }
		if ($i > $end) { last; }
		print $_;
	}
	close(IN);
	print "<hr>\n";

	$next = $in{'page'} + $pagelog;
	$back = $in{'page'} - $pagelog;

	print "<table>\n";
	if ($back >= 0) {
		print "<td><form action=\"$script\" method=\"$method\">\n";
		print "<input type=hidden name=mode value=past>\n";
		print "<input type=hidden name=pastlog value=\"$in{'pastlog'}\">\n";
		print "<input type=hidden name=page value=\"$back\">\n";
		print "<input type=submit value=\"前の$pagelog件\"></td></form>\n";
	}
	if ($next < $i) {
		print "<td><form action=\"$script\" method=\"$method\">\n";
		print "<input type=hidden name=mode value=past>\n";
		print "<input type=hidden name=pastlog value=\"$in{'pastlog'}\">\n";
		print "<input type=hidden name=page value=\"$next\">\n";
		print "<input type=submit value=\"次の$pagelog件\"></td></form>\n";
	}
	print "</table>\n</body>\n</html>\n";
	exit;
}

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

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

#------------------#
#  チェックモード  #
#------------------#
sub check {
	print &header;
	print "<h2>Check Mode</h2>\n";
	print "<UL>\n";

	# 3ファイルチェック
	foreach ("$logfile", "$htm_dir$htmfile", "$htm_dir$nexthtm") {
		# パス
		if (-e $_) { print "<LI>$_ のパス：OK\n"; }
		else { print "<LI>$_ のパス：NG\n"; }

		# パーミッション
		if (-r $_ && -w $_) { print "<LI>$_ のパーミッション：OK\n"; }
		else { print "<LI>$_ のパーミッション：NG\n"; }
	}

	# ロックディレクトリ
	print "<LI>ロック形式：";
	if ($lockkey == 0) { print "ロック設定なし\n"; }
	else {
		if ($lockkey == 1) { print "symlink\n"; }
		else { print "mkdir\n"; }

		($lockdir) = $lockfile =~ /(.*)[\\\/].*$/;
		print "<LI>ロックディレクトリ：$lockdir\n";

		if (-d $lockdir) { print "<LI>ロックディレクトリのパス：OK\n"; }
		else { print "<LI>ロックディレクトリのパス：NG → $lockdir\n"; }

		if (-r $lockdir && -w $lockdir && -x $lockdir) {
			print "<LI>ロックディレクトリのパーミッション：OK\n";
		} else {
			print "<LI>ロックディレクトリのパーミッション：NG → $lockdir\n";
		}
	}

	# 過去ログ
	print "<LI>過去ログ：";
	if ($pastkey == 0) { print "設定なし\n"; }
	else {
		print "設定あり\n";

		# NOファイル
		if (-e $nofile) { print "<LI>NOファイルパス：OK\n"; }
		else { print "<LI>NOファイルのパス：NG → $nofile\n"; }
		if (-r $nofile && -w $nofile) { print "<LI>NOファイルパーミッション：OK\n"; }
		else { print "<LI>NOファイルパーミッション：NG → $nofile\n"; }

		# ディレクトリ
		if (-d $pastdir) { print "<LI>過去ログディレクトリパス：OK\n"; }
		else { print "<LI>過去ログディレクトリのパス：NG → $pastdir\n"; }
		if (-r $pastdir && -w $pastdir && -x $pastdir) {
			print "<LI>過去ログディレクトリパーミッション：OK\n";
		} else {
			print "<LI>過去ログディレクトリパーミッション：NG → $pastdir\n";
		}
	}

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