#!/usr/bin/perl

#┌─────────────────────────────────
#│ Sun Board v4
#│ sunbbs.cgi - 2008/03/07
#│ Copyright (c) KentWeb
#│ webmaster@kent-web.com
#│ http://www.kent-web.com/
#└─────────────────────────────────

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

&decode;
if ($mode eq 'form') { &form; }
elsif ($mode eq 'regist') { &regist; }
elsif ($mode eq 'admin') { &admin; }
elsif ($mode eq 'mente') { &mente; }
elsif ($mode eq 'edit') { &edit; }
elsif ($mode eq 'userdel') { &userdel; }
&error("不明な処理です");

#-------------------------------------------------
#  投稿処理
#-------------------------------------------------
sub regist {
	# チェック
	if ($no_wd) { &no_wd; }
	if ($jp_wd) { &jp_wd; }
	if ($urlnum > 0) { &urlnum; }

	# 投稿キーチェック
	if ($regist_key && !$whatsnew) {
		require $regkeypl;

		if ($in{'regikey'} !~ /^\d{4}$/) {
			&error("投稿キーが入力不備です。<p>投稿フォームに戻って再読込み後、指定の数字を入力してください");
		}

		# 投稿キーチェック
		# -1 : キー不一致
		#  0 : 制限時間オーバー
		#  1 : キー一致
		local($chk) = &registkey_chk($in{'regikey'}, $in{'str_crypt'});
		if ($chk == 0) {
			&error("投稿キーが制限時間を超過しました。<p>投稿フォームに戻って再読込み後、指定の数字を再入力してください");
		} elsif ($chk == -1) {
			&error("投稿キーが不正です。<p>投稿フォームに戻って再読込み後、指定の数字を入力してください");
		}
	}

	# チェック
	if ($whatsnew) {
		if ($in{'pass'} ne $pass) { &error("パスワードが違います"); }
	} else {
		# ホスト名チェック
		&axscheck;
		if ($in{'name'} eq "") { &error("なまえの記入がありません"); }
	}
	if ($in{'comment'} eq "") { &error("コメントに記入がありません"); }
	if ($in{'email'} && $in{'email'} !~ /^[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,6}$/) {
		&error("Ｅメールの入力内容が不正です<br>");
	}
	if ($in{'sub'} eq "") { $in{'sub'} = "無題"; }
	if ($in{'url'} eq "http://") { $in{'url'} = ''; }

	open(DAT,"+< $logfile") || &error("Open Error: $logfile");
	eval "flock(DAT, 2);";
	my $top = <DAT>;

	# 二重投稿の禁止
	local($num,$name,$com) = (split(/<>/, $top))[0,2,5];
	if ($in{'name'} eq $name && $in{'comment'} eq $com) {
		close(DAT);
		&error("二重投稿は禁止です");
	}

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

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

	# 日付処理、タグ有効キー
	if ($whatsnew) {
		$date = $in{'date'};
	} else {
		$date = &get_time;
		$in{'tag'} = 0;
	}

	# ログを更新
	local($i, @file, @data);
	seek(DAT, 0, 0);
	while (<DAT>) {
		$i++;

		# 最大数以内
		if ($i < $max) {
			push(@file,$_);

		# 最大数超
		} else {
			unshift(@data,$_) if ($pastkey);
		}
	}

	# 現行ログ更新
	unshift (@file,"$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pw<>$in{'tag'}<>\n");
	seek(DAT, 0, 0);
	print DAT @file;
	truncate(DAT, tell(DAT));
	close(DAT);

	# 過去ログ更新
	if ($pastkey && @data > 0) {
		&pastlog;
	}

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

	# クッキー発行
	if (!$whatsnew) { &set_cookie($in{'name'},$in{'email'},$in{'url'},$in{'pwd'}); }

	# メール通知処理
	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=\"$bbscgi?mode=form\">Post</a>\n";
	}

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

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

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

	# タイトル部
	if ($t_gif eq '') {
	  	print WR "<b style=\"color:$t_color;font-size:$t_size\">$title</b>\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</p></div><hr>\n";

	# 記事を展開
	my ($next, $last);
	if ($page == 2) {
		$next = $pagelog+1;
		$last = $max;
	} else {
		$next = 0;
		$last = $pagelog;
	}

	my $i = 0;
	open(IN,"$logfile") || &error("Open Error: $logfile");
	while ( my $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 (@file > $pagelog && $page == 1) {
	  	print WR "<td><form action=\"$htm_url$nexthtm\">";
	  	print WR "<input type=\"submit\" value=\"次ページ\"></td></form>\n";
	} elsif (@file > $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=\"$registcgi\" method=\"post\">\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>\n";
		print WR "</tr></table><br clear=\"all\">\n";
	}

	# 著作権を表示（削除不可）
	print WR "<div align=\"center\" style=\"font-size:10px;font-family:Verdana,Helvetica,Arial\"><!-- $ver -->\n";
	print WR "- <a href=\"http://www.kent-web.com/\" target=\"_top\">SunBoard</a> -\n";
	print WR "</div>\n</body>\n</html>\n";
	close(WR);
}

#-------------------------------------------------
#  表示部戻り
#-------------------------------------------------
sub location {
	# 投稿確認画面の表示
	if ($msg_check) {
		print &header;
		print qq|<br><br><div align="center">\n|;
		print qq|<h3>処理は正常に完了しました</h3>\n|;
		print qq|<form action="$htm_url$htmfile">\n|;
		print qq|<input type="submit" value="閲覧画面に戻る">\n|;
		print qq|</div></form>\n|;
		print qq|</body></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 userdel {
	# フォームチェック
	if ($in{'no'} eq "") { &error("記事NOが入力されていません"); }
	if ($in{'pwd'} eq "") { &error("削除キーが入力されていません"); }

	# ログファイルを開く
	local($i, $k, $flag, @file);
	open(DAT,"+< $logfile") || &error("Open Error: $logfile");
	eval "flock(DAT, 2);";
	while (<DAT>) {
		$i++;
		my ($num,$date,$name,$email,$sub,$com,$url,$host,$pwd) = split(/<>/);

		if ($in{'no'} == $num) {
			$k = $i;
			$flag = 1;

			if ($pwd eq '') {
				$flag = -1;
				last;
			} elsif (&decrypt($in{'pwd'}, $pwd) != 1) {
				$flag = -2;
				last;
			}
			next;
		}
		push(@file,$_);
	}

	if (!$flag || $flag == -2) {
		close(DAT);
		&error("認証できません");
	} elsif ($flag == -1) {
		close(DAT);
		&error("削除キーが設定されていません");
	}

	# ログ更新
	seek(DAT, 0, 0);
	print DAT @file;
	truncate(DAT, tell(DAT));
	close(DAT);

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

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

#-------------------------------------------------
#  管理用初期画面
#-------------------------------------------------
sub admin {
	# ログイン画面
	if ($in{'pass'} eq '') {
		print &header;
		print qq|<table width="100%"><tr>\n|;
		print qq|<th bgcolor="$obi_color"><font color="$s_color">入室画面</font></th>\n|;
		print qq|</tr></table>\n|;
		print qq|<div align="center"><h4>管理用パスワードを入力して下さい</h4>\n|;
		print qq|<form action="$registcgi" method="post">\n|;

		if ($whatsnew) {
		    print qq|<input type="radio" name="mode" value="form" checked>書込\n|;
		    print qq|<input type="radio" name="mode" value="admin">ログ<br>\n|;
		} else {
		    print qq|<input type="hidden" name="mode" value="admin">\n|;
		}

		print qq|<input type="password" name="pass" size="12">\n|;
		print qq|<input type="submit" value=" 認証 "></form></div>\n|;
		print qq|</body></html>\n|;
		exit;

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

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

		&mente;

	# 削除
	} elsif ($in{'ope'} eq 'del' && $in{'no'}) {

		local($i, $k, @file);
		open(DAT,"+< $logfile") || &error("Open Error: $logfile");
		eval "flock(DAT, 2);";
		while (<DAT>) {
			my ($no) = split(/<>/);
			$i++;
			if ($in{'no'} == $no) {
				$k = $i;
				next;
			}
			push(@file,$_);
		}
		seek(DAT, 0, 0);
		print DAT @file;
		truncate(DAT, tell(DAT));
		close(DAT);

		if ($k > $pagelog) {
			&html_regist($nexthtm, 2);
		} elsif ($k <= $pagelog) {
			&html_regist("$htm_dir$htmfile", 1);
			&html_regist("$htm_dir$nexthtm", 2) if ($pagelog < @file);
		}
	}

	# 管理画面
	print &header;
	print <<"EOM";
[<a href="$htm_url$htmfile">戻る</a>]
<table width="100%">
<tr>
	<th bgcolor="$obi_color"><font color="$s_color">管理画面</font></th>
</tr>
</table>
<form action="$registcgi" method="post">
<input type="hidden" name="mode" value="admin">
<input type="hidden" name="pass" value="$in{'pass'}">
処理：
<select name="ope">
<option value="mente">修正
<option value="del">削除
</select>
<input type="submit" value="送信する">
<dl>
EOM

	# ログ表示
	open(IN,"$logfile") || &error("Open Error: $logfile");
	while (<IN>) {
		my ($no,$date,$name,$email,$sub,$com,$url,$host) = split(/<>/);
		$name = "<a href=\"mailto:$email\">$name</a>" if ($email);
		$com =~ s/<br>//g;
		$com =~ s/</&lt;/g;
		$com =~ s/>/&gt;/g;
		if (length($com) > 60) { $com = substr($com,0,58) . "..."; }

		print qq|<dt><hr><input type="radio" name="no" value="$no">\n|;
		print qq|[<b>$no</b>] <b>$sub</b> 投稿者：$name 日付：$date ホスト：$host\n|;
		print qq|<dd>$com\n|;
	}
	close(IN);

	print <<EOM;
<dt><hr>
</dl>
</form>
</body>
</html>
EOM
	exit;
}

#-------------------------------------------------
#  記事編集
#-------------------------------------------------
sub mente {
	if ($in{'num'}) {

		# タグキー
		if (!$whatsnew) { $in{'tag'} = 0; }

		local($i, $k, @file);
		open(DAT,"+< $logfile") || &error("Open Error: $logfile");
		eval "flock(DAT, 2);";
		while (<DAT>) {
			$i++;
			my ($no,$date,$name,$email,$sub,$com,$url,$host,$pwd,$tag) = split(/<>/);

			if ($in{'num'} == $no) {
				$k = $i;
				$_ = "$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pwd<>$in{'tag'}<>\n";
			}
			push(@file,$_);
		}

		seek(DAT, 0, 0);
		print DAT @file;
		truncate(DAT, tell(DAT));
		close(DAT);

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

		&admin;
	}

	print &header;
	print <<"EOM";
[<a href="$htm_url$htmfile">戻る</a>]
<table width="100%">
<tr>
	<th bgcolor="$obi_color"><font color="$s_color">管理画面</font></th>
</tr>
</table>
<form action="$registcgi" method="post">
<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

	my ($no,$date,$name,$email,$sub,$com,$url,$ho,$pw,$tag);

	# ログ展開
	open(IN,"$logfile") || &error("Open Error: $logfile");
	while (<IN>) {
		($no,$date,$name,$email,$sub,$com,$url,$ho,$pw,$tag) = split(/<>/);

		last if ($in{'no'} == $no);
	}
	close(IN);

	$com =~ s/<br>/\n/g;

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

	if ($whatsnew) {
		if ($tag == 1) { $chk="checked"; } else { $chk=""; }
		print "<tr><td><b>タグ有効</b></td>";
		print "<td><input type=\"checkbox\" name=\"tag\" value=\"1\" $chk> ";
		print "（コメント内でタグを有効にする場合はチェック）</td></tr>\n";
	}

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

#-------------------------------------------------
#  過去ログ生成
#-------------------------------------------------
sub pastlog {
	my $past_flag;

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

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

	# 過去ログを開く
	open(LOG,"+< $pastfile") || &error("Open Error: $pastfile");
	eval "flock(LOG, 2);";
	my @past = <LOG>;

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

		# カウントファイル更新
		$count = sprintf("%04d", $count+1);
		seek(NO, 0, 0);
		print NO $count;
		truncate(NO, tell(NO));

		# 過去ログ名再定義
		$pastfile = "$pastdir$count.dat";
		@past = ();

		# 前番を閉じる
		close(LOG);

		# 新番をオープン
		open(LOG,"+> $pastfile") || &error("Write Error: $pastfile");
		eval "flock(LOG, 2);";
	}

	close(NO);

	my @temp;
	foreach (@data) {
		my ($pno,$pdate,$pname,$pmail,$psub,$pcom,$purl,$pho,$ppw,$ptag) = split(/<>/);
		if ($pmail) { $pname = "<a href=\"mailto:$pmail\">$pname</a>"; }
		if ($purl) {
			if ($purl !~ m|https?://|i) { $purl = "http://$purl"; }
			$purl = "&lt;<a href=\"$purl\" target='_top'>URL</a>&gt;";
		}
		if ($whatsnew) {
			$pcom = &tagview($pcom) if ($ptag == 1);
			push(@temp,"<hr>[<b>$pno</b>] <b>$psub</b> Date：$pdate $purl<br><blockquote>$pcom</blockquote>\n");
		} else {
			push(@temp,"<hr>[<b>$pno</b>] <b>$psub</b> 投稿者：<b>$pname</b> 投稿日：$pdate $purl<br><blockquote>$pcom</blockquote>\n");
		}
	}

	# 過去ログ更新
	unshift(@past,@temp);
	seek(LOG, 0, 0);
	print LOG @past;
	truncate(LOG, tell(LOG));
	close(LOG);

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

#-------------------------------------------------
#  メール送信
#-------------------------------------------------
sub mail_to {
	# メールタイトルを定義
	my $msub = &base64("[$title : $no] $in{'sub'}");

	my $com = $in{'comment'};
	$com =~ s/<br>/\n/ig;
	$com =~ s/&amp;/＆/g;
	$com =~ s/&quot;/"/g;
	$com =~ s/&lt;/＜/g;
	$com =~ s/&gt;/＞/g;

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

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

$com
EOM

	# sendmail起動
	open(MAIL,"| $sendmail -t -i") || &error("送信失敗");
	print MAIL "To: $mailto\n";
	print MAIL "From: $mailto\n";
	print MAIL "Subject: $msub\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";
	foreach ( split(/\n/, $mbody) ) {
		&jcode::convert(\$_, 'jis', 'sjis');
		print MAIL $_, "\n";
	}
	close(MAIL);
}

#-------------------------------------------------
#  BASE64変換
#-------------------------------------------------
#	とほほのWWW入門で公開されているルーチンを
#	参考にしました。( http://tohoho.wakusei.ne.jp/ )
sub base64 {
	local($sub) = @_;
	&jcode::convert(\$sub, 'jis', 'sjis');

	$sub =~ s/\x1b\x28\x42/\x1b\x28\x4a/g;
	$sub = "=?iso-2022-jp?B?" . &b64enc($sub) . "?=";
	$sub;
}
sub b64enc {
	local($ch)="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	local($x, $y, $z, $i);
	$x = unpack("B*", $_[0]);
	for ($i=0; $y=substr($x,$i,6); $i+=6) {
		$z .= substr($ch, ord(pack("B*", "00" . $y)), 1);
		if (length($y) == 2) {
			$z .= "==";
		} elsif (length($y) == 4) {
			$z .= "=";
		}
	}
	$z;
}

#-------------------------------------------------
#  クッキー発行
#-------------------------------------------------
sub set_cookie {
	local(@cook) = @_;

	my @t = gmtime(time + 60*24*60*60);
	my @m = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	my @w = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');

	# 国際標準時を定義
	my $gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT",
			$w[$t[6]], $t[3], $m[$t[4]], $t[5]+1900, $t[2], $t[1], $t[0]);

	# 保存データをURLエンコード
	my $cook;
	foreach (@cook) {
		s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
		$cook .= "$_<>";
	}

	# 格納
	print "Set-Cookie: SUN_BOARD=$cook; expires=$gmt\n";
}

#-------------------------------------------------
#  パスワード暗号
#-------------------------------------------------
sub encrypt {
	my $inpw = shift;

	my @SALT = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/');
	srand;
	my $salt = $SALT[int(rand(@SALT))] . $SALT[int(rand(@SALT))];
	crypt($inpw, $salt) || crypt ($inpw, '$1$' . $salt);
}

#-------------------------------------------------
#  パスワード照合
#-------------------------------------------------
sub decrypt {
	my ($in, $dec) = @_;

	my $salt = $dec =~ /^\$1\$(.*)\$/ && $1 || substr($dec, 0, 2);
	if (crypt($in, $salt) eq $dec || crypt($in, '$1$' . $salt) eq $dec) {
		return 1;
	} else {
		return 0;
	}
}

#-------------------------------------------------
#  禁止ワードチェック
#-------------------------------------------------
sub no_wd {
	local($flg);
	foreach ( split(/,/, $no_wd) ) {
		if (index("$in{'name'} $in{'sub'} $in{'comment'}",$_) >= 0) {
			$flg = 1; last;
		}
	}
	if ($flg) { &error("禁止ワードが含まれています"); }
}

#-------------------------------------------------
#  日本語チェック
#-------------------------------------------------
sub jp_wd {
	if ($in{'comment'} !~ /[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]/) {
		&error("コメントに日本語が含まれていません");
	}
}

#-------------------------------------------------
#  URL個数チェック
#-------------------------------------------------
sub urlnum {
	local($com) = $in{'comment'};
	local($num) = ($com =~ s|(https?://)|$1|ig);
	if ($num > $urlnum) {
		&error("コメント中のURLアドレスは最大$urlnum個までです");
	}
}

#-------------------------------------------------
#  時間取得
#-------------------------------------------------
sub get_time {
	$ENV{'TZ'} = "JST-9";
	my ($min,$hour,$mday,$mon,$year,$wday) = (localtime(time))[1..6];
	my @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');

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

