#!/usr/bin/perl

#====↑｢perl｣言語が使用できるパスを指定(確認必須)====

#===================================================
#    Illust-ColorfulRes Ver3.18
#    Copyright (c) 2001-2002 K3 All rights reserved.
#    WebSite:BBS Box (管理人:kinako)
#    URL:http://k-cubic.com/cgi/
#    E-Mail:kanrinin@k-cubic.com
#
#    2002/02/05 Ver3.00 Ver3.00完成。
#    2002/02/07 Ver3.10 チェックモード追加。
#    2002/02/16 Ver3.11 細かなバグ修正完了。
#    2002/02/18 Ver3.12 OS&ブラウザでHTML分岐。
#    2002/02/19 Ver3.13 Error判定を細かく変更。
#    2002/02/20 Ver3.14 チェックモード強化。
#    2002/02/22 Ver3.15 削除時のバグ修正。
#    2002/04/28 Ver3.17 Opera対策。
#    2002/05/24 Ver3.18 タグ復活関数修正。
#===================================================
#$ver = '3.18'; #バージョン情報(変更不要)

#====初期設定開始========================================================================================
#====重要項目===========================================================================================
$jcode_file = '../perl-lib/jcode.pl';        #日本語コード変換モジュールの場所。
$data_file = './bbs_aozora.dat';          #データファイルの場所。
$bbs_file = './aozora-keijiban.cgi';   #この掲示板のパス。(掲示板のファイル名)
$lock_file = './lock.lock';        #ロックファイル(ディレクトリ)の場所。
$lock_flag = '0';                  #ファイルロックの方法。
                                   #flock関数が使えれば0、mkdir関数を使う場合は1、ロックしない場合は2。
                                         #flock関数が使えれば0、mkdir関数を使う場合は1、ロックしない場合は2。

$check_flag = '0';    #チェックモード選択。(チェックモードで動作確認するときは1を入れる)
                      #チェックモードで確認すると、ある程度のエラー原因を調査・修正できる。

#====基本項目===========================================================================================
$cookie_name = 'illustbbs'; #cookie名。
$cookie_flag = '0';         #クッキー保存の方法。トクトク系の場合は1、それ以外は0。
$master_pass = 'xyz';       #管理者パスワード。(すべての記事を削除できる)
$save_max = '9000';          #記事の最大記録数。(実際には最大+10まで記録)
$page_max = '30';           #１ページに表示する親記事の最大数。
$up_flag = '1';             #返信時の処理方法。(返信された親記事を一番上にする場合は1、しない場合は0)

$title = 'AozoraViewer掲示板';        #掲示板のタイトル。(head内の<title></title>の部分)
$head = '&nbsp;&nbsp;&nbsp;SoSO Message Board for AozoraViewer';         #掲示板のタイトル。(実際にページに表示されるタイトル。<img>も使用可能。｢'｣は使用不可)
#$return_page = 'TOP';                     #右上のリンクで移動する先。(右上のリンクで表示するテキスト)
$url = 'http://wwwxx.xxx.xx.xx/~xxx/';    #右上のリンクの移動先URLを指定。
$text_size = '9pt';                       #文字の大きさ。(CSSのfont-size指定。smallなどの指定も可能)
$box_posi = '120px';                      #記事や書き込みフォームの位置。(px指定のみ・背景イラストの位置＋イラストの幅＋20px程度)
$box_width = '412px';                     #ボックスの横幅。(px指定のみ)

#====色項目(全体色)========================================================================================
$back_color = '#ffffff';    #基本背景色。
$text_color = '#6666cc';    #基本文字色。

$name_color = '#88bb88';    #名前などの文字色。
$title_color = '#88bbbb';   #タイトル(ヘッダ)などの文字色。
$sub_color = '#aabb88';     #日付時間、記事No.などの文字色

$link_color = '#6699cc';    #未読リンク色。
$vlink_color = '#99cc66';   #既読リンク色。
$alink_color = '#dddddd';   #アクティブなリンク色。

$ftext_color = '#000000';   #入力フォームの文字色。
$fborder_color = '#6666cc'; #入力フォームの枠色。
$fback_color = '#ffffff';   #非アクティブな入力フォームの背景色。
$aback_color = '#ddddff';   #アクティブな入力フォームの背景色。
$bback_color = '#ddddff';   #書き込み/削除などのボタンの背景色。

#====色項目(選択色)========================================================================================
#    色選択の■には$text_colorの色が使われる。
#    $text_colorはメッセージ、$title_colorは記事タイトルの文字色。
#    同じ形式を並べたり、削除したりして数を変更可能。

#====Color-====
$text_color[0] = '#6633cc';
$title_color[0] = '#6633cc';

#====Color-1====
$text_color[1] = '#33cc66';
$title_color[1] = '#33cc66';

#====Color-2====
$text_color[2] = '#330099';
$title_color[2] = '#330099';

#====Color3-====
$text_color[3] = '#FF9900';
$title_color[3] = '#FF9900';

#====Color-4====
$text_color[4] = '#FF0000';
$title_color[4] = '#FF0000';

#====Color-5====
$text_color[5] = '#660033';
$title_color[5] = '#660033';

#====Color-6====
$text_color[6] = '#666666';
$title_color[6] = '#666666';

#====Color-7====
$text_color[7] = '#000000';
$title_color[7] = '#000000';

$kaigyou = '4';        #色選択ボタンを改行する場所。(改行なしは0)
                       #6色で改行したい場合は$kaigyou = '6';とする。

#====画像指定(全体画像)============================================================================================
#$illust = './bds-logo.gif';            #イラスト画像。

#$illust_top = '120px';             #イラストの上端の位置。
#$illust_left = '10px';             #イラストの左端の位置。

#====追加機能項目=================================================================================================
#    サーバーのサポートが必要(メール送信)・掲示板が荒らさせる可能性(タグの使用)・処理が重たくなる(禁止ワード・禁止ホスト)
#    以上のようなことに気をつけて追加機能を設定すること。
#    まずは追加機能項目を変更せずに動作確認を行うほうが、失敗しにくい。

$sendmail_pass = '';      #メール送信(メール送信を使いたい場合、ここにsendmailのパスを入れる)
$mail = '';               #メール送信(さらに、送信先メールアドレスを入れる)

$tag_flag ='0';           #タグの使用(タグを許可する場合は1を入れる)
$ok_tag[0] = 'a';         #使用を許可するタグ。(開始タグと閉じタグで対になっているタグ。font、aなど)
$ok_stag[0] = 'img';      #使用を許可するタグ。(対になっていないタグ。imgなど)

$kinshi_flag = '0';       #禁止ワード＆ホスト(禁止ワードを含む書き込み、禁止ホストからの書き込みの場合に記録しないなら1を入れる)
$kinshi_word[0] = '';     #禁止ワード(使用を禁止する言葉を入れる。同じ形式で数字を増やして並べて、複数指定可能)
$kinshi_host[0] = '';     #禁止ホスト(書き込みを禁止するホスト・IPを入れる。ホストの一部でも禁止可能。禁止ワードと同じように複数指定可能)
                          #禁止ワード・ホストともに一文字ワイルドカード｢*｣、文字列ワイルドカード｢.*｣を使用可能。

#====初期設定終了==================================================================================================
#    ここから下は変更不要。
#====初期設定終了==================================================================================================
if ($check_flag) { &check_mode; }        #チェックモードの場合、チェックモードへ。

#====変数の取得====
$save_flag = '1';                        #1のままなら、記録する。
$color_num = @text_color - 1;            #$color_numは配列の最大添数。
$mysite = 'http://www.35-35.net/aozora/';

require $jcode_file;                     #日本語変換ライブラリのセット。
&form_read;                              #フォームデータ取得。
&agent_check;                            #OS＆ブラウザ簡易判定。
if (!($form{'action'} eq 'write' && !$form{'cookie'})) { &cookie_read; }  #クッキーデータ取得。

#====フォーム要素・クッキー要素の指定====
#    date,num,name,comment,host,passは必須フォーム要素。
#    name,passは必須クッキー要素。

$form_e[0] = 'title';
$form_e[1] = 'mail';
$form_e[2] = 'home';
$form_e[3] = 'color';
$form_e[4] = 'res_num';
$form_e[5] = 'last_res';
$cookie_e[0] = 'mail';
$cookie_e[1] = 'home';
$cookie_e[2] = 'color';

#====書込処理====
if ($form{'action'} eq 'write') {

	$date_now = &time_read;     #現在時刻取得。
	$host = &host_read;         #ホスト取得。

	#====フォームデータ処理====
	$form{'comment'} =~ s/\r/<br>/g;                                   #改行を<br>タグに変更。
	$form{'comment'} = &link_on($form{'comment'});                     #リンクをはる。
	if ($tag_flag) { $form{'comment'} = &tag_on($form{'comment'}); }   #タグ使用可の場合、タグを復活させる。
	if ($form{'name'} eq '' || $form{'comment'} eq '') { &error("名前、記事の書き込みがありません。"); }                #名前、記事がない場合はエラー。
	if ($form{'home'} && !($form{'home'} =~ /http:\/\//i)) { $form{'home'} = 'http://' . $form{'home'}; }             #Webのリンクに「http://」を付ける。
	if ($kinshi_flag) { &kinshi_off("$form{'comment'}$form{'name'}$form{'title'}$form{'home'}$form{'mail'}",$host); } #禁止ワードを使う場合、禁止ワード処理に移る。
	if ($form{'res_num'} > 0) { $form{'comment'} = "＞No\.$form{'res_num'}<br>" . $form{'comment'}; }                 #返信の場合、返信No.を追加する。

	#====クッキーデータ処理＆記録====
	if ($form{'cookie'}) {
		$cookie_value = "name+$form{'name'}\,pass+$form{'pass'}";
		$cookie{'name'} = $form{'name'};
		$cookie{'pass'} = $form{'pass'};
		foreach $element (@cookie_e) {
			$cookie_value .= "\," . $element . "+" . $form{$element};
			$cookie{$element} = $form{$element};
		}
		$cookie_value .= "\,k3+K3";
	} else { $cookie_value = "name+\,pass+\,k3+k3";}
	&cookie_save;                 #クッキーの記録。

	#====ロックしてデータ読み込み====
	if (!&lock) { &error("掲示板が混み合っています。しばらく待ってからアクセスしてください。"); }
	&file_read;

	#====記録データ整理====
	$line_num = @maindata;

	if (&double_check) { $save_flag = '0'; }    #二重投稿確認＆記事No取得、二重投稿なら記録しないようにする。
	$save_value = "date+$date_now\,num+$num\,name+$form{'name'}\,comment+$form{'comment'}\,pass+$form{'pass'}\,host+$host";
	foreach $element (@form_e) { $save_value .= "\," . $element . "+" . $form{$element}; }
	$save_value .= "\,k3+K3\n";

	if ($save_flag) {                           #記録ができるなら、記録へ。
		#====各処理を行う====
		if ($up_flag && $form{'res_num'} > 0) { &kiji_up; }                     #記事を上げる場合、記事を上げる。
		if ($line_num >= $save_max + 10) { &over_del; $line_num = @maindata; }  #データ数が最大+10を超えていれば、10記事削除。
		unshift(@maindata,$save_value);                                         #@maindataに記録データを挿入。
		@maindata = sort(@maindata); @maindata = reverse(@maindata);

		&file_save;
		if ($sendmail_pass && $form{'pass'} ne $master_pass) { &send_mail; }  #メール機能を使う場合、メール送信。
	}
	&unlock;                        #ファイルをアンロック。

#====削除処理====
} elsif ($form{'action'} eq 'delert') {
	if (!&lock) { &error("掲示板が混み合っています。しばらく待ってからアクセスしてください。"); }
	&file_read;
	if (!$form{'del_pass'} || $form{'del_num'} < 1) { &error("削除パス、もしくは記事ナンバーがありません。記事ナンバーは半角英数にして下さい。"); }
	if (&line_delert) { &file_save; } else { &error("削除対象記事がないか、削除パスが間違っています。"); }    #記事の削除があった場合、ファイルに書き込みを行う。
	&unlock;                        #ファイルのアンロック。

#====通常時のファイルデータ取得====
} else {
	if (!&lock) { &error("掲示板が混み合っています。しばらく待ってからアクセスしてください。"); }
	&file_read;
	&unlock;                        #ファイルのアンロック。
}

#====表示情報整理====
&data_sort;        #データ整理・並び替え。
&top_end;          #ページの最初の記事、最後の記事、次のページの最初、前のページの最初を取得。

#====ＨＴＭＬ記述処理====
&html_head;        #HTMLのヘッダ部分。
&html_form;        #HTMLのフォーム部分。
if ($page_end >= 0) {
	foreach $line ($page_top .. $page_end) {
		($dummy, $file{'color'}, $data) = split(/\,\,/,$display_data[$line]);
		print $data;             #HTML記事・返信部分。
		&html_kijibottom;        #HTML記事の底の部分。
	}
}
&html_foot;        #HTMLフッター部分。

exit;

#====エラー処理=====================================================================================
sub error {
	local ($msg) = $_[0];

	print "Content-type: text/html; charset=Shift_JIS\n\n";        #Content-type宣言。
	print "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
	print "<html>\n<head>\n";
	print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\">\n";
	print "<title>エラー</title>\n";
	print "<style type=\"text/css\">\n<!--\n";
	print "*{ font-size : 100%; color : #6666cc; }\n";
	print "h1{ margin : 60px 8% 0px 8%; padding : 2px 10px 2px 10px; font-weight : 700; border-style : solid; border-color : #6666cc; border-width : 0px 0px 1px 16px;}\n";
	print "p{ margin : 20px 10% 0px 10%; }\n";
	print "-->\n</style>\n";
	print "</head>\n<body>\n";
	print "<h1>エラー</h1>\n";
	print "<p>$msg</p>\n";
	print "</body>\n</html>";

	exit;
}
#====チェックモード=====================================================================================
sub check_mode {
	local ($msg) = '';

	#====エラーチェック====
	if (! -f $jcode_file) { $msg .= "・Error 日本語変換ライブラリ(jcode.pl)がありません。日本語変換ライブラリの位置を確認してください。<br>\n"; }
	elsif (! -x $jcode_file) { $msg .= "・Error 日本語変換ライブラリ(jcode.pl)が実行できません。日本語変換ライブラリやライブラリを置いたディレクトリのパーミッションを確認してください。<br>\n"; }
	if (! -f $data_file) { $msg .= "・Error データファイル($data_file)がありません。データファイルの位置を確認してください。<br>\n"; }
	elsif (! -w $data_file) { $msg .= "・Error データファイル($data_file)に書き込みできません。データファイルやデータファイルを置いているディレクトリのパーミッションを確認してください。<br>\n"; }
	if (!$lock_flag) {
		eval { flock( LOCK, 8 ) ; } ;
		if ($@) { $msg .= "・Error flock関数が使えません。ロック方法を変更してください。<br>\n"; }
		elsif (-d $lock_file) {
			if (rmdir($lock_file)) {
				if (open(LOCK,">$lock_file")) { close(LOCK); $msg .= "・Error ロックディレクトリ($lock_file)がありました。ロックディレクトリを自動削除して、ロックファイル($lock_file)を自動で作成しました。もう一度チェックモードでロックファイルの有無を確認してください。<br>\n"; }
				else { $msg .= "・Error ロックディレクトリ($lock_file)がありました。ロックディレクトリを自動削除して、ロックファイル($lock_file)を自動で作成しようとしましたが、作成に失敗しました。ロックファイルを作成してください。<br>\n"; }
			} else { $msg .= "・Error ロックディレクトリ($lock_file)がありました。自動削除を試みましたが、失敗しました。ロックディレクトリを削除して、同じ名前のロックファイルを作成してください。<br>\n"; }
		} elsif (! -f $lock_file) {
			if (open(LOCK,">$lock_file")) { close(LOCK); $msg .= "・Error ロックファイル($lock_file)がありません。ロックファイルを自動で作成しました。もう一度チェックモードでロックファイルの有無を確認してください。<br>\n"; }
			else { $msg .= "・Error ロックファイル($lock_file)がありません。自動作成を試みましたが、失敗しました。ロックファイルがあるかどうか、もしくは位置を確認してください。<br>\n"; }
		}
	} elsif ($lock_flag == 1) {
		if  (! -w './') { $msg .= "・Error CGI設置ディレクトリに書き込みができないため、ロックディレクトリを作成できません。CGIを置いているディレクトリのパーミッションを確認してください。<br>\n"; }
		if (-d $lock_file) {
			if (rmdir($lock_file)) { $msg .= "・Error ロックディレクトリ($lock_file)が残っていました。ロックディレクトリを自動で削除しました。<br>\n"; }
			else { $msg .= "・Error ロックディレクトリ($lock_file)が残っています。自動削除を試みましたが、失敗しました。ロックディレクトリを削除してください。<br>\n"; }
		} elsif (-f $lock_file) {
			if (unlink($lock_file)) { $msg .= "・Error ロックファイル($lock_file)がありました。ロックファイルを自動で削除しました。mkdir関数のロックは、ロックファイルではなく、ロックディレクトリを作成します。<br>\n"; }
			else { $msg .= "・Error ロックファイル($lock_file)がありました。自動削除を試みましたが、失敗しました。mkdir関数のロックは、ロックディレクトリ作成してロックするので、同じ名前のファイルはエラーを起こします。今あるロックファイルを削除してください。<br>\n"; }
		}
	}
	if (! -x $sendmail_pass && $sendmail_pass) { $msg .= "・Error sendmailが使えません。sendmailが使えるか、パスが正しいか確認してください。<br>\n"; }
	if ($msg) { $msg .= '<br>以上のエラーはCGIスクリプトとデータファイル、日本語変換ライブラリとロックファイルの位置も同じディレクトリした場合のもので、標準的なものです。サーバーによって設定が異なるので、設定する値やファイルの位置などは必ずプロバイダなどで確認したものを使ってください。'; }
	else { $msg = 'ファイルの位置やパーミッションなどにエラーはありませんでした。ただし、あくまで標準的な設置の場合なので、CGIがうまく動かない場合もあります。設定などは必ずプロバイダなどで確認したものを使ってください。'; }

	#====チェック結果====
	print "Content-type: text/html\n\n";        #Content-type宣言。
	print "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
	print "<html>\n<head>\n";
	print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=Shift_JIS\">\n";
	print "<title>チェックモード</title>\n";
	print "<style type=\"text/css\">\n<!--\n";
	print "*{ font-size : 100%; color : #6666cc; }\n";
	print "h1{ margin : 20px 8% 0px 8%; padding : 2px 10px 2px 10px; font-weight : 700; border-style : solid; border-color : #6666cc; border-width : 0px 0px 1px 16px;}\n";
	print "p{ margin : 20px 10% 0px 10%; }\n";
	print "-->\n</style>\n";
	print "</head>\n<body>\n";
	print "<h1>チェックモードの結果</h1>\n";
	print "<p>$msg</p>\n";
	print "</body>\n</html>";

	exit;
}
#====OS＆ブラウザ簡易判定関数===============================================================================
sub agent_check{
	local($dummy) = $ENV{'HTTP_USER_AGENT'};

	#====OS判定====
	if ($dummy =~ /Windows/) { $os = 10; }  #Windows
	elsif ($dummy =~ /Mac/i) { $os = 20; }  #Macintosh
	else { $os = 0; }                       #etc
	#====ブラウザ判定====
	if ($dummy =~ /Opera/) { $brw = 30; }         #Opera
	elsif ($dummy =~ /MSIE/) { $brw = 10; }       #Internet Explorer
	elsif ($dummy =~ /Netscape6/) { $brw = 21; }  #Netscape6
	elsif ($dummy =~ /Gecko/ && !($dummy =~ /Netscape/)) { $brw = 40; }      #Mozilla
	elsif ($dummy =~ /Mozilla/ && !($dummy =~ /Compatible/)) { $brw = 20; }  #Netscape Navigator
	else { $brw = 0; }      #etc

}
#====フォームデータ取得関数===============================================================================
sub form_read {
	local($name, $value, $pair);
	read(STDIN, $form_data, $ENV{'CONTENT_LENGTH'});   #フォームデータを取得。
	local(@pairs) = split(/&/,$form_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;
		$value =~ s/\,/，/g;
		$value =~ s/\+/＋/g;
		$value =~ s/</&lt;/g;
		$value =~ s/>/&gt;/g;
		&jcode'convert(*value,'sjis');#'
		$form{$name} = $value;
	}
}
#====クッキーデータ取得関数==============================================================================
sub cookie_read {
	local($name, $value, $pair);
	local($cookie) = $ENV{'HTTP_COOKIE'};        #クッキーデータを取得。
	local(@pairs) = split(/;/,$cookie);
	foreach $pair (@pairs) {
		($name, $value) = split(/=/, $pair);
		$name =~ s/ //g;
		$cookie{$name} = $value;
	}
	@pairs = split(/\,/,$cookie{$cookie_name});
	foreach $pair (@pairs) {
		($name, $value) = split(/\+/, $pair);
		$cookie{$name} = $value;
	}
}
#====現在時刻取得関数=====================================================================================
sub time_read {
	$ENV{'TZ'} = "JST-9";            #日本時間に合わせる。
	local(@date) = localtime(time);  #時間を取得。
	$date[5] += 1900;
	$date[4] = sprintf("%02d",$date[4] + 1);
	$date[3] = sprintf("%02d",$date[3]);
	$date[2] = sprintf("%02d",$date[2]);
	$date[1] = sprintf("%02d",$date[1]);
	$date[0] = sprintf("%02d",$date[0]);
	$date[6] = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat') [$date[6]];
	local($date) = "$date[5]/$date[4]/$date[3]($date[6]) $date[2]:$date[1]:$date[0]";
	$date;
}
#====ホスト取得=======================================================================================
sub host_read {
	local($address) = $ENV{'REMOTE_ADDR'};
	local($host) = gethostbyaddr(pack("C4",split(/\./,$address)),2);
	if (!$host) { $host = $address; }
	$host;
}
#====リンク設定関数======================================================================================
sub link_on { 
	local($_) = $_[0]; 
	$_ =~ s/([^=^\"]|^)((http|ftp):[!#-9A-~]+)/$1<a href=\"$2\" target=\"_blank\">$2<\/a>/g;  #リンク設定。
	$_ =~ s/([!#-9A-~\-\_]+\@[!#-9A-~\-\_\.]+)/<a href=\"mailto:$1\">$1<\/a>/g;               #mailto設定。
	$_; 
}#"
#====タグ復活関数====================================================================================
sub tag_on {
	local($_) = $_[0];
	foreach $dummy (@ok_tag) { if ($dummy) { $_ =~ s/&lt;($dummy[!-:A-~\s\=\?]*?)&gt;(.*)&lt;\/$dummy&gt;/<$1>$2<\/$dummy>/ig; } }
	foreach $dummy (@ok_stag) { if ($dummy) { $_ =~ s/&lt;($dummy.*?)&gt;/<$1>/ig; } }
	$_;
}
#====禁止ワード処理関数====================================================================================
sub kinshi_off {
	local($dummy,$kinshi_word,$kinshi_host) = ('',$_[0],$_[1]);
	if ($kinshi_word[0]) {
		foreach $dummy (@kinshi_word){
			if ($kinshi_word =~ /$dummy/i) { $save_flag = 0; last;}  #禁止ワードをチェック。
		}
	}
	if ($kinshi_host[0]) {
		foreach $dummy (@kinshi_host){
			if ($kinshi_host =~ /$dummy/i) { $save_flag = 0; last;}  #禁止ホストをチェック。
		}
	}
}
#====クッキーデータ記録関数==============================================================================
sub cookie_save {
	$ENV{'TZ'} = "GMT";                            #標準時間に合わせる。
	local(@date) = localtime(time + 60 * 86400);   #記録期間を取得。
	$date[5] += 1900;
	$date[3] = sprintf("%02d",$date[3]);
	$date[2] = sprintf("%02d",$date[2]);
	$date[1] = sprintf("%02d",$date[1]);
	$date[0] = sprintf("%02d",$date[0]);
	local($wday) = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday') [$date[6]];
	local($month) = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec') [$date[4]];
	local($gmt) = "$wday, $date[3]\-$month\-$date[5] $date[2]:$date[1]:$date[0] GMT";
	$toku2_cookie = '';
	if ($cookie_flag) { $toku2_cookie = "<meta http-equiv=\'Set-Cookie\' content=\'$cookie_name=$cookie_value; expires=$gmt\'>\n"; }  #トクトクの場合のクッキー記録用。
	else { print "Set-Cookie: $cookie_name=$cookie_value; expires=$gmt\n"; }  #通常のクッキー保存。
}
#====ファイルロック関数==============================================================================
sub lock {
	local($lock) = '0';
	foreach $i (0..10) {
		#====flock関数のファイルロック====
		if (!$lock_flag) {
			if (open(LOCK,">$lock_file")) {
				if (flock(LOCK, 6)) { $lock = 1; last ;}
			} else { &error("掲示板が混み合っているか、ロックファイルが開けません。"); }
		#====mkdir関数のファイルロック====
		} elsif ($lock_flag == 1) {
			if (mkdir($lock_file, 0755)) { $lock = 1; last; }
			elsif ($i == 0) {
				($lock_time) = (stat("$lock_file"))[9];
				if ($lock_time < time - 600) { rmdir("$lock_file"); next; }
			}
		#====ファイルロックなしの場合====
		} else { $lock = 1; last; }
		sleep(1);
	}
	$SIG{'TERM'} = $SIG{'PIPE'} = $SIG{'HUP'} = "sigexit";
	$lock;
}
sub sigexit {
	if ($lock_flag == 1) { rmdir("$lock_file"); exit; }
}
#====ファイルデータ取得関数==============================================================================
sub file_read {
	if (!open(FILE,"$data_file")) { &error("データファイルが読み込めません。"); }
	@maindata = <FILE>;
	close(FILE);
}
#====ファイルアンロック関数==============================================================================
sub unlock {
	if (!$lock_flag) { close(LOCK); }                #flock関数のファイルアンロック。
	elsif ($lock_flag == 1) { rmdir($lock_file); }   #mkdir関数のファイルアンロック。
}
#====二重投稿防止＆記事Ｎｏ取得関数======================================================================
sub double_check {
	local($pair, $end, $name, $value);
	local($double) = '0';
	if ($line_num < 10) { $end = $line_num - 1; } else { $end = 9; }
	foreach $line (0..$end) {
		local (@pairs) = split(/\,/,$maindata[$line]);
		foreach $pair (@pairs) {
			($name, $value) = split(/\+/,$pair);
			$file{$name} = $value;
		}
		if ($file{'comment'} eq $form{'comment'}) { $double = 1; last; }
		if (!$line) { $num = $file{'num'} + 1; }
	}
	if (!$num) { $num = 1; }
	$double;
}
#====記事アップ関数====================================================================================
sub kiji_up {
	local($end) = $line_num - 1;
	foreach $line (0..$end) {
		%file = ('');
		local (@pairs) = split(/\,/,$maindata[$line]);
		foreach $pair (@pairs) {
			($name, $value) = split(/\+/,$pair);
			$file{$name} = $value;
		}

		if ($form{'res_num'} == $file{'res_num'} || $form{'res_num'} == $file{'num'}) {
			$file{'last_res'} = $num;
			$maindata[$line] = "date+$file{'date'}\,num+$file{'num'}\,name+$file{'name'}\,comment+$file{'comment'}\,pass+$file{'pass'}\,host+$file{'host'}";
			foreach $element (@form_e) { $maindata[$line] .= "\," . $element . "+" . $file{$element}; }
			$maindata[$line] .= "\,k3+K3\n";
		}
	}
}
#====オーバー分記事削除=================================================================================
sub over_del {
	local($end) = $line_num - 1;
	local($del_line) = $end;
	local($dummy, $line) = ('0','0');
	foreach $dummy (0..9) {
		$end = $line_num - $dummy - 1;
		$del_line = $end;
		foreach $line (0..$end) {
			%file = ('');
			local (@pairs) = split(/\,/,$maindata[$line]);
			foreach $pair (@pairs) {
				($name, $value) = split(/\+/,$pair);
				$file{$name} = $value;
			}
			if ($line == 0) { $del_num = $file{'num'}; }
			if (!$file{'last_res'}) { $file{'last_res'} = $file{'num'}; }
			if ($file{'last_res'} <= $del_num) {
				$del_num = $file{'last_res'};
				$del_line = $line;
			}
		}
		splice(@maindata,$del_line,1);
	}
}
#====データ保存関数====================================================================================
sub file_save {
	if (!open(FILE,">$data_file")) { &error("データファイルに書き込めませんでした。"); }
	print FILE @maindata;
	close(FILE);
}
#====メール送信関数==============================================================================
sub send_mail {

	local($msg, $dummy) = ('','');
	if ($mail) {
		$msg = "To: $mail\n";
		if ($form{'mail'}) { $msg .= "From: $form{'mail'}\n"; }
		$msg .= "Subject: Write to $title\n\n";

		#====メール本文====
$dummy = <<MAIL;
Name : $form{'name'}
E-mail : $form{'mail'}
Web : $form{'home'}
Title : $form{'title'}
Message : 
$form{'comment'}
MAIL

		#====メッセージのデコード====
		$msg .= $dummy;
		$msg =~ s/<br>/\n/g;
		$msg =~ s/&lt;/</g;
		$msg =~ s/&gt;/>/g;
		$msg =~ s/&amp;/&/g;
		&jcode'convert(*msg, "jis");

		#====メール送信====
		open(MAIL, "| $sendmail_pass $mail");
		print MAIL $msg;
		close(MAIL);
	}
}#'
#====記事削除関数=======================================================================================
sub line_delert {
	local($del,$res_num,$dummy,$last_res) = ('0','0','0','0');
	local($end) = @maindata - 1;
	foreach $line (0..$end) {
		local (@pairs) = split(/\,/,$maindata[$line]);
		foreach $pair (@pairs) {
			($name, $value) = split(/\+/,$pair);
			$file{$name} = $value;
		}

		#====パスワードチェック====
		if ($form{'del_num'} == $file{'num'}) {
			if ($form{'del_pass'} eq $file{'pass'} || $form{'del_pass'} eq $master_pass) {
				if ($file{'res_num'}) { $res_num = $file{'res_num'}; }
				splice(@maindata,$line,1);
				$del = 1; last;
			}
		}
	}
	#====返信記事削除の場合、上げていた処理を戻す====
	if ($res_num && $up_flag) {
		$end = $end - 1;
		foreach $line (0..$end) {
			local (@pairs) = split(/\,/,$maindata[$line]);
			foreach $pair (@pairs) {
				($name, $value) = split(/\+/,$pair);
				$file{$name} = $value;
			}
			if (($res_num == $file{'res_num'} || $res_num == $file{'num'}) && $dummy == 0) { $dummy = 1; $last_res = $file{'num'}; }
			if ($res_num == $file{'res_num'} || $res_num == $file{'num'}) {
				$file{'last_res'} = $last_res;				 
				$maindata[$line] = "date+$file{'date'}\,num+$file{'num'}\,name+$file{'name'}\,comment+$file{'comment'}\,pass+$file{'pass'}\,host+$file{'host'}";
				foreach $element (@form_e) { $maindata[$line] .= "\," . $element . "+" . $file{$element}; }
				$maindata[$line] .= "\,k3+K3\n";
			}

		}
	}
	$del;
}
#====表示データ範囲決定関数=========================================================================================
sub top_end {
	if ($form{'top_num'} eq '' || $form{'top_num'} < 0) { $page_top = 0; } else { $page_top = $form{'top_num'}; }
	$save_end = @display_data;                                 #記事総数。
	$page_next = $page_top + $page_max;                        #次のページの最初の記事。
	$page_back = $page_top - $page_max;                        #前のページの最初の記事。
	$page_end = $page_next - 1;                                #表示するページの最後の記事。
	if ($page_end >= $save_end) { $page_end = $save_end - 1; } #記事総数と最後の記事を比べて、最後の記事を調整。
}
#====返信No.削除関数====================================================================================
sub res_off {
	local($_) = $_[0];
	$_ =~ s/^＞No\.[!#-9A-~]+<br>//i;
	$_;
}
#====ファイルデータ整理関数============================================================================================
sub data_sort {
	local ($pair, $line, $name, $value, %dam_data);
	@maindata = reverse(@maindata);
	foreach $line (@maindata) {
		%file = ('');
		local (@pairs) = split(/\,/,$line);
		foreach $pair (@pairs) {
			($name, $value) = split(/\+/,$pair);
			$file{$name} = $value;
		}

		#====カラーの処理====
		if (!$file{'color'} || $file{'color'} > $color_num) { $file{'color'} = 0; }

		#====タイトルの処理====
		if (!$file{'title'}) { $file{'title'} = "No Title"; }
		$file{'re_title'} = $file{'title'};
		$file{'re_title'} =~ s/\"/”/g; $file{'re_title'} =~ s/\'/’/g;

		#====メールとWebの処理====
		if ($file{'mail'}) { $file{'mail'} = "[<a href=\"mailto:$file{'mail'}\">Mail</a>]"; }
		if ($file{'home'}) { $file{'home'} = "[<a href=\"$file{'home'}\" target=\"_blank\">Web</a>]"; }

		#====親記事の処理====
		if (!$file{'res_num'}) {

$dummy_data = <<HTML;
<div class="kiji_box" style="border-color : $text_color[$file{'color'}];">
<div class="title_box"><span class="title" style="color : $title_color[$file{'color'}];">$file{'title'}</span></div>
<div class="comment_box"><SPAN style="color : $text_color[$file{'color'}];">$file{'comment'}</span></div>
<div class="sub_box"><span class="name">$file{'name'} $file{'mail'} $file{'home'}</span><br><span class="sub">$file{'date'} No.$file{'num'}</span>　<input class="button" type="button" value=" Res " name="hennshin" onclick="res_form($file{'num'},'Re:$file{'re_title'}')"></div>
HTML

			if (!$file{'last_res'}) { $file{'last_res'} = $file{'num'}; }
			$dam_num = sprintf("%06d",$file{'last_res'});
			$dam_data{$file{'num'}} = "$dam_num\,\,$file{'color'}\,\,$dummy_data";  #親記事作成。($file{'color'}は親記事の色の継承用)

		#====返信記事の処理====
		} elsif ($dam_data{$file{'res_num'}}) {
			($dummy, $oya_color, $data) = split(/\,\,/,$dam_data{$file{'res_num'}});
			$file{'comment'} = &res_off($file{'comment'});    #返信No.の削除。

$dummy_data = <<HTML;
<div class="res_box" style="border-color : $text_color[$oya_color];">
<div class="title_box"><span class="title" style="color : $title_color[$file{'color'}];">$file{'title'}</span></div>
<div class="comment_box"><SPAN style="color : $text_color[$file{'color'}];">$file{'comment'}</span></div>
<div class="sub_box"><span class="name">$file{'name'} $file{'mail'} $file{'home'}</span> <span class="sub">$file{'date'} No.$file{'num'}</span></div>
</div>
HTML

			$dam_data{$file{'res_num'}} .= $dummy_data;      #返信記事を親記事に付け足す。
		} 
	}
	foreach (keys %dam_data) { push(@display_data,$dam_data{$_}); }
	@display_data = sort(@display_data);      #ソート。
	@display_data = reverse(@display_data);   #逆順にする。
}#"
#====ヘッダ関数===============================================================================
sub html_head {

if ($brw != 20) {
$ie_width = <<HTML;
.width_name{
  width : 120px;
}
.width_title{
  width : 320px;
}
.width_pass{
  width : 48px;
}
HTML
}
if ($brw != 20 && !$tag_flag) { $l_height = "  line-height : 125%;\n"; }
if ($brw == 10) {
$form_style = <<HTML;
input, textarea, select{
  font-size : $text_size;
  background-color : $fback_color;
  border-top : 1px solid $fborder_color;
  border-right : 1px solid $fborder_color;
  border-bottom : 1px solid $fborder_color;
  border-left : 1px solid $fborder_color;
  color : $ftext_color;
}
.border_off{
  border-style : none;
  background-color : transparent;
}
.button{
  font-size : $text_size;
  background-color : $bback_color;
  overflow : visible;
}
HTML
}
#if ($illust) { $background_img = "  background-image : url($illust);\n"; }  #背景指定。

print "Content-type: text/html; Charset=Shif_JIS\n\n";           #Content-type宣言。

#====ヘッダ部分====
print <<HTML;
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
$toku2_cookie<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>$title</title>
<style type="text/css">
<!--
*{
  margin : 0px;
  padding : 0px;
  font-size : 100%;
  word-break : break-all;
  text-align : left;
}
body{
  color : $text_color;
  font-size : $text_size;
  background-color : $back_color;
  background-repeat : no-repeat;
  background-attachment : fixed;
  margin-top: 1%;
  margin-bottom:1%;
$background_img}
table{ 
  color : $text_color;
  font-size : $text_size;
  padding : 0px;
  border : 0px none #ffffff;
  margin-left: auto;
  margin-right: auto;
  border-collapse : collapse;
}
td{
  color : $text_color;
  font-size : $text_size;
  padding : 0px;
  border : 0px none #ffffff;
}
a{
  color : $link_color;
  text-decoration : none;
}
a:LINK{
  color : $link_color;
  text-decoration : none;
}
a:VISITED{
  color : $vlink_color;
  text-decoration : none;
}
a:HOVER{
  color : $alink_color;
}
a:ACTIVE{
  color : $alink_color;
}
h1{
  color : $title_color;
  font-weight : 700;
}
$form_style$ie_width.center{
  text-align : center;
}
.right{
  text-align : right;
}
.small{
  font-size : 90%;
}
.link_top, .copyright{
  text-align : right;
}
.copyright{
  padding-bottom : 10px;
}
.title{
  color : $title_color;
  font-weight : 700;
}
.name{
  color : $name_color;
  font-weight : 700;
}
.sub{
  color : $sub_color;
  font-size : 90%;
}
#frame{
  margin-left : $box_posi;
}
.kiji_box{
  width : $box_width;
  border-color : $text_color;
  border-style : solid;
  border-width : 1px;
  margin-top: 20px;
  margin-left: auto;
  margin-right: auto;
  padding : 10px 10px 10px 10px;
}
.comment_box{
  margin-top : 8px;
$l_height}
.res_box{
  border-color : $text_color;
  border-style : solid;
  border-width : 1px 0px 0px 0px;
  margin-top : 10px;
  padding : 10px 0px 0px 0px;
}
.reload_button{
  width : $box_width;
  text-align: right;
  padding: 0px;
  margin-top: 0px;
  margin-botom: 0px;
  margin-left: auto;
  margin-right: auto;
}
#header{
  text-align: center;
}
#footer{
  padding: 0px;
  margin-left: auto;
  margin-right: auto;
}
body { 
scrollbar-face-color: #ffffff; scrollbar-highlight-color: #000000; scrollbar-shadow-color: #000000; 
scrollbar-arrow-color: #000000; scrollbar-track-color: #ffffff; scrollbar-darkshadow-color: #ffffff; 
scrollbar-base-color: #ffffff; scrollbar-3d-light-color: #ffffff 
}
-->
</style>
<script type="text/javascript">
<!--
//書き込みボタン。
function write_push(){
	if (document.info.name.value == "") { alert("名前が未入力です。"); }
	else if (document.info.comment.value == "") { alert("コメントが未入力です。"); }
	else { document.info.action.value = "write"; document.info.submit(); }
}
//削除ボタン。
function delete_push(){
	if (document.info.del_num.value == "" || document.info.del_pass.value == "") { alert("記事No、もしくは削除パスが未入力です。");	}
	else { document.info.action.value = "delert"; document.info.submit(); }
}
//返信ボタン。
function res_form(num,re_title) {
	document.info.res_num.value = num;
	document.info.title.value = re_title;
	document.info.kakikomi.value = " Res:No." + num + " ";
	document.info.kakinaoshi.value = " Reset ";
	window.scroll(0,0);
	ten_num = 0;
	if(document.all) tenmetu();
}
function tenmetu() {
	document.info.kakikomi.style.backgroundColor="$fback_color";
	ten_num++;
	ten_timer = setTimeout("tenmetu_2()",300);
}
function tenmetu_2() {
	document.info.kakikomi.style.backgroundColor="$bback_color";
	if (ten_num < 6) { ten_timer = setTimeout("tenmetu()",300); }
}
//リセットボタン。
function re_set(){
	document.info.kakikomi.value = " Write ";
	document.info.kakinaoshi.value = " Clear ";
	document.info.res_num.value = 0;
}
//戻るボタン。
function back_push() {
	document.info.top_num.value = "$page_back";
	document.info.action.value = "back";
	document.info.submit();
}
//次へボタン。
function next_push() {
	document.info.top_num.value ="$page_next";
	document.info.action.value = "next";
	document.info.submit();
}
//フォーカスイン。
function focus_in(in_input) {
	if(document.all) in_input.style.backgroundColor="$aback_color";
}
//フォーカスアウト。
function focus_out(out_input) {
	if(document.all) out_input.style.backgroundColor="$fback_color";
}
-->
</script>
</head>
HTML

}
#====フォーム関数====================================================================================
sub html_form{

if (!$cookie{'color'} || $cookie{'color'} > $color_num) { $cookie{'color'} = 0; }
$checked[$cookie{'color'}] = ' checked';

#====書き込みフォーム部分====
print<<HTML;
<body>
<div id="header">
<img src="http://www.35-35.net/aozora/image/aozora_header.png" alt="AozoraViewerヘッダ画像" usemap="#aozoramenu" style="border:none;">
<map id="aozoramenu" name="aozoramenu">
	<area shape="rect" coords="2,2,94,44" target="_blank" href="http://www.35-35.co.jp/" alt="SoSO Corporation" />
	<area shape="rect" coords="42,2,244,20" target="_blank" href="http://www.linuxmania.jp/" alt="LinuxMania" />
</map>
      <table style="border-style: solid none; border-color: rgb(153, 153, 153) -moz-use-text-color; border-width: 1px medium;" border="0" cellpadding="0" cellspacing="0" width="800">
       <tbody><tr>
                  <td style="padding:2px; padding-top: 5px;"> <a href="http://www.35-35.net/aozora/">TOP</a> > <b>$title</b></td>
                </tr>
      </tbody></table>
</div>
<br>
<div class="reload_button">[<a href="http://www.35-35.co.jp/cgi-local/aozora-keijiban.cgi">リロードする</a>]</div>
<br>
<div id="frame" align="center">
<form action="$bbs_file" method="POST" name="info">
<input type="hidden" name="res_num"><input type="hidden" name="action"><input type="hidden" value="0" name="top_num">
<table>
  <tbody>
    <tr>
      <td class="right">Name：</td>
      <TD><input size="20" type="text" name="name" value="$cookie{'name'}" maxlength="24" class="width_name" onblur="focus_out(this)" onfocus="focus_in(this)">&nbsp&nbsp<label for="cookie"><input type="checkbox" name="cookie" id="cookie" value="1" class="border_off" checked><span class="small">Cookie保存</span></label></td>
    </tr>
    <tr>
      <td class="right">E-Mail(未入力でもOK)：</td>
      <td><input size="20" type="text" name="mail" value="$cookie{'mail'}" maxlength="200" class="width_name" onblur="focus_out(this)" onfocus="focus_in(this)"></td>
    </tr>
    <tr>
      <td class="right">Title：</td>
      <td><input size="34" type="text" name="title" value="" maxlength="30" class="width_title" onblur="focus_out(this)" onfocus="focus_in(this)"></td>
    </tr>
    <tr>
      <td class="right">Message：</td>
      <td><textarea rows="4" cols="34" name="comment" class="width_title" onblur="focus_out(this)" onfocus="focus_in(this)"></textarea></td>
    </tr>
    <tr>
      <td class="right">Web(未入力でもOK)：</td>
      <td><input size="34" type="text" name="home" value="$cookie{'home'}" maxlength="200" class="width_title" onblur="focus_out(this)" onfocus="focus_in(this)"></td>
    </tr>
    <tr>
      <td class="right">Color：</td>
      <td>
HTML

foreach $num (0..$color_num) {
	if ($num == $kaigyou && $kaigyou) { print "";}
	print "       <label for=\"$num\"><input id=\"$num\" type=\"radio\" name=\"color\" class=\"border_off\" value=\"$num\"$checked[$num]><span style=\"color : $text_color[$num];\">■</span></label>\n";
}

print<<HTML;
      </td>
    </tr>
    <tr>
      <td class="right">Pass：</td>
      <td><input type="password" name="pass" size="6" value="$cookie{'pass'}" maxlength="8" class="width_pass" onblur="focus_out(this)" onfocus="focus_in(this)">　<input type="button" name="kakikomi" value=" Write " class="button" onclick="write_push()">　<input type="reset" name="kakinaoshi" value=" Clear " class="button" onclick="re_set()"></td>
    </tr>
  </tbody>
</table>

HTML

}
#====記事(底)関数====================================================================================
sub html_kijibottom {
	print "</div>\n";
}
#====フッター関数====================================================================================
sub html_foot {

#====フッター部分====
print<<HTML;
<BR>
<table>
  <tbody>
    <tr>
      <td>No.：<input type="text" size="6" name="del_num" class="width_pass" onblur="focus_out(this)" onfocus="focus_in(this)"> Pass：<input type="password" maxlength="8" size="6" name="del_pass" class="width_pass" onblur="focus_out(this)" onfocus="focus_in(this)">　<input type="button" value=" Delete " name="del" class="button" onclick="delete_push()"></td>
      <td class="right">　
HTML

	if ($page_top != 0) { print "<input type=\"button\" name=\"back\" value=\" Back \" class=\"button\" onclick=\"back_push()\">"; }
	if ($save_end > $page_end + 1) { print "\　<input type=\"button\" name=\"next\" value=\" Next \" class=\"button\" onclick=\"next_push()\">"; }

print<<HTML;
</td>
    </tr>
  </tbody>
</table>
</form>
</div>
<BR>
<div id="footer">
<table>
<tr>
<td width="100%" style="text-align:left;"><a href="http://www.35-35.net/aozora/" target="_top"><font size="-2"><u>TOP ページへ</u></font></a></td> 
</tr>
<tr><td width="100%" bgcolor="#ffffff" >
<br><font size="-1"></font><font color="#009900" size="-1">Copyright (c) 1999-2008 by SoSO Corporation. All rights reserved.</font></td>
</tr></table>
</div>
<BR>
<BR>
</body>
</html>
HTML

}
