#!/usr/local/bin/perl

#┌─────────────────────────────────
#│ SUN BOARD : sunbbs.cgi - 2011/07/10
#│ Copyright (c) KentWeb
#│ http://www.kent-web.com/
#└─────────────────────────────────

# モジュール宣言
use strict;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use lib "./lib";
use Jcode;

# 設定ファイル認識
require "./init.cgi";
my %cf = &init;

# データ受理
$CGI::POST_MAX = $cf{maxdata};
my $cgi = CGI->new;
&error($cgi->cgi_error) if ($cgi->cgi_error);
my %in = &parse_form($cgi);

# 条件分岐
if ($in{mode} eq 'form') { &bbs_form; }
if ($in{mode} eq 'find') { &find_data; }
if ($in{mode} eq 'note') { &note_page; }
if ($in{mode} eq "past" && $cf{pastkey}) { &past_log; }
&error("不明な処理です");

#-----------------------------------------------------------
#  投稿フォーム
#-----------------------------------------------------------
sub bbs_form {
	# レス処理
	$in{res} =~ s/\D//g;
	my %res;
	if ($in{res}) {
		my $flg;
		open(IN,"$cf{logfile}") || &error("open err: $cf{logfile}");
		while (<IN>) {
			my ($no,$sub,$com) = (split(/<>/))[0,4,5];
			if ($in{res} == $no) {
				$flg++;
				$res{sub} = $sub;
				$res{com} = $com;
				last;
			}
		}
		close(IN);

		if (!$flg) { &error("該当記事が見つかりません"); }

		$res{sub} =~ s/^Re://g;
		$res{sub} =~ s/\[\d+\]\s?//g;
		$res{sub} = "Re:[$in{res}] $res{sub}";
		$res{com} = "&gt; $res{com}";
		$res{com} =~ s/<br>/\n&gt; /ig;
	}

	# クッキー取得
	my @cook = &get_cookie;
	$cook[2] ||= 'http://';

	# 画像認証作成
#	my ($str_plain,$str_crypt);
#	if ($cf{use_captcha} > 0) {
#		require $cf{captcha_pl};
#		($str_plain, $str_crypt) = cap::make( $cf{captcha_key}, $cf{cap_len} );
#	}

	open(IN,"$cf{tmpldir}/form.html") or &error("open err: form.html");
	my $tmpl = join('', <IN>);
	close(IN);

	$tmpl =~ /(.+)<!-- captcha_begin -->(.+)<!-- captcha_end -->(.*)/s;
	my ($top, $cap, $bot) = ($1, $2, $3);

	foreach ( $top, $bot ) {
		s/!bbs_cgi!/$cf{cgi_url}\/$cf{bbs_cgi}/g;
		s/!regist_cgi!/$cf{cgi_url}\/$cf{regist_cgi}/g;
		s/!admin_cgi!/$cf{cgi_url}\/$cf{admin_cgi}/g;
		s/!homepage!/$cf{homepage}/g;
		s/!name!/$cook[0]/;
		s/!email!/$cook[1]/;
		s/!url!/$cook[2]/;
		s/!sub!/$res{sub}/;
		s/!comment!/$res{com}/;
	}

	print $cgi->header(-charset => 'shift_jis');
	print $top;

#	# 画像認証
#	if ($cf{use_captcha} > 0) {
#		$cap =~ s/!captcha_cgi!/$cf{captcha_cgi}/g;
#		$cap =~ s/!str_crypt!/$str_crypt/g;
#		print $cap;
#	}

	# フッタ
	if ($bot =~ /(.+)(<\/body[^>]*>.*)/si) {
		print "$1$cf{copyright}$2";
	} else {
		print "$bot$cf{copyright}";
		print $cgi->end_html;
	}
	exit;
}

#-----------------------------------------------------------
#  ワード検索
#-----------------------------------------------------------
sub find_data {
	# 条件
	$in{cond} =~ s/\D//g;

	# 検索条件プルダウン
	my %op = (1 => 'AND', 0 => 'OR');
	my $op_cond;
	foreach (1,0) {
		if ($in{cond} eq $_) {
			$op_cond .= qq|<option value="$_" selected>$op{$_}\n|;
		} else {
			$op_cond .= qq|<option value="$_">$op{$_}\n|;
		}
	}

	# 検索実行
	Jcode::convert(\$in{word}, 'sjis');
	my ($hit, @log) = &search($in{word}, $in{cond}, $cf{logfile}) if ($in{word} ne '');

	# テンプレート
	open(IN,"$cf{tmpldir}/find.html") or &error("open err: find.html");
	my $tmpl = join('', <IN>);
	close(IN);

	# 分割
	$tmpl =~ /(.+)<!-- loop_begin -->(.+)<!-- loop_end -->(.+)/s;
	my ($head, $loop, $foot) = ($1, $2, $3);

	foreach ($head, $foot) {
		s/!bbs_url!/$cf{html_url}\/body.html/g;
		s/!bbs_cgi!/$cf{bbs_cgi}/g;
		s/<!-- op_cond -->/$op_cond/;
		s/!word!/$in{word}/;
	}

	# ヘッダ部
	print $cgi->header(-charset => "shift_jis");
	print $head;

	# ループ部
	foreach my $log (@log) {
		my ($no,$date,$name,$eml,$sub,$com,$url,$host,$pw,$tim) = split(/<>/, $log);
		$name = qq|<a href="mailto:$eml">$name</a>| if ($eml);
		$com  = &autolink($com) if ($cf{autolink});
		$com =~ s/([>]|^)(&gt;[^<]*)/$1<span style="color:$cf{ref_col}">$2<\/span>/g if ($cf{ref_col});
		$url  = qq|<a href="$url" target="_blank">$url</a>| if ($url);

		my $tmp = $loop;
		$tmp =~ s/!sub!/$sub/g;
		$tmp =~ s/!date!/$date/g;
		$tmp =~ s/!name!/$name/g;
		$tmp =~ s/!home!/$url/g;
		$tmp =~ s/!comment!/$com/g;
		print $tmp;
	}

	# フッタ部
	if ($foot =~ /(.+)(<\/body[^>]*>.*)/si) {
		print "$1$cf{copyright}$2";
	} else {
		print "$foot$cf{copyright}";
		print $cgi->end_html;
	}
	exit;
}

#-----------------------------------------------------------
#  検索実行
#-----------------------------------------------------------
sub search {
	my ($word, $cond, $file, $list) = @_;

	# キーワードを配列化
	$word =~ s/　/ /g;
	my @wd = split(/\s+/, $word);

	# 検索処理
	my ($i, @log);
	open(IN,"$file") or &error("open err: $file");
	while (<IN>) {
		my ($no,$date,$nam,$eml,$sub,$com,$url,$hos,$pw,$tim) = split(/<>/);

		my $flg;
		foreach my $wd (@wd) {
			if (index("$nam $eml $sub $com $url", $wd) >= 0) {
				$flg++;
				if ($cond == 0) { last; }
			} else {
				if ($cond == 1) { $flg = 0; last; }
			}
		}
		next if (!$flg);

		$i++;
		if ($list > 0) {
			next if ($i < $in{pg} + 1);
			next if ($i > $in{pg} + $list);
		}

		push(@log,$_);
	}
	close(IN);

	# 検索結果
	return ($i, @log);
}

#-----------------------------------------------------------
#  留意事項表示
#-----------------------------------------------------------
sub note_page {
	open(IN,"$cf{tmpldir}/note.html") or &error("open err: note.html");
	print $cgi->header(-charset => "shift_jis");
	print <IN>;
	close(IN);
	exit;
}

#-----------------------------------------------------------
#  過去ログ画面
#-----------------------------------------------------------
sub past_log {
	# 過去ログ番号
	open(IN,"$cf{nofile}") or &error("open err: $cf{nofile}");
	my $pastnum = <IN>;
	close(IN);

	my $pastnum = sprintf("%04d", $pastnum);
	$in{pno} =~ s/\D//g;
	$in{pno} ||= $pastnum;

	# プルダウンタグ作成
	my $op_pno;
	for ( my $i = $pastnum; $i > 0; $i-- ) {
		$i = sprintf("%04d", $i);

		if ($in{pno} == $i) {
			$op_pno .= qq|<option value="$i" selected>$i\n|;
		} else {
			$op_pno .= qq|<option value="$i">$i\n|;
		}
	}

	# ページ数
	my $pg = $in{pg} || 0;

	# 初期化
	my ($hit,$page_btn,@log);

	# 対象ログ定義
	my $file = "$cf{pastdir}/" . sprintf("%04d", $in{pno}) . ".cgi";

	# ワード検索
	if ($in{find} && $in{word} ne '') {

		# 検索
		Jcode::convert(\$in{word}, 'sjis');
		($hit, @log) = &search($in{word}, $in{cond}, $file, $in{list});

		# 結果
		$page_btn = "検索結果：<b>$hit</b>件 &nbsp;&nbsp;" . &pgbtn_old($hit, $in{pno}, $pg, 'past');

	# ログ一覧
	} else {

		# 過去ログオープン
		my $i = 0;
		open(IN,"$file") or &error("open err: $file");
		while(<IN>) {
			$i++;
			next if ($i < $pg + 1);
			next if ($i > $pg + $cf{pg_max});

			push(@log,$_);
		}
		close(IN);

		# 繰越ボタン作成
		$page_btn = &pgbtn_old($i, $in{pno}, $pg);
	}

	# プルダウン作成（検索条件）
	my %op = &make_op;

	# テンプレート読み込み
	my ($flg,$loop);
	open(IN,"$cf{tmpldir}/past.html") or &error("open err: past.html");
	my $tmpl = join('', <IN>);
	close(IN);

	# テンプレート分割
	$tmpl =~ /(.+)<!-- loop_begin -->(.+)<!-- loop_end -->(.+)/s;
	my ($head, $loop, $foot) = ($1, $2, $3);

	if ($in{change}) { $in{word} = ''; }

	# 文字置換
	foreach ($head, $foot) {
		s/!past_num!/$in{pno}/g;
		s/!bbs_url!/$cf{html_url}\/body.html/g;
		s/!([a-z]+_cgi)!/$cf{$1}/g;
		s/<!-- op_pno -->/$op_pno/g;
		s/<!-- op_(\w+) -->/$op{$1}/g;
		s/!word!/$in{word}/g;
		s/!page_btn!/$page_btn/g;
	}

	# 画面表示
	print $cgi->header(-charset => 'shift_jis');
	print $head;
	foreach (@log) {
		my ($no,$date,$nam,$eml,$sub,$com,$url,$hos,$pw,$tim) = split(/<>/);
		$nam = qq|<a href="mailto:$eml">$nam</a>| if ($eml);
		$com = &autolink($com) if ($cf{autolink});

		my $tmp = $loop;
		$tmp =~ s/!sub!/$sub/g;
		$tmp =~ s/!date!/$date/g;
		$tmp =~ s/!name!/$nam/g;
		$tmp =~ s/!url!/$url/g;
		$tmp =~ s/!comment!/$com/g;
		print $tmp;
	}
	# フッタ部
	if ($foot =~ /(.+)(<\/body[^>]*>.*)/si) {
		print "$1$cf{copyright}$2";
	} else {
		print "$foot$cf{copyright}";
		print $cgi->end_html;
	}
	exit;
}

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

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

#-----------------------------------------------------------
#  繰越ボタン作成 [ 過去ログ ]
#-----------------------------------------------------------
sub pgbtn_old {
	my ($i, $pno, $pg, $stat) = @_;

	# ページ繰越定義
	my $next = $pg + $cf{pg_max};
	my $back = $pg - $cf{pg_max};

	my $link;
	if ($stat eq 'past') {
		my $wd = &url_enc($in{word});
		$link = "$cf{bbs_cgi}?mode=$in{mode}&pno=$pno&find=1&word=$wd";
	} else {
		$link = "$cf{bbs_cgi}?mode=$in{mode}&pno=$pno";
	}

	# ページ繰越ボタン作成
	my $pg_btn;
	if ($back >= 0 || $next < $i) {
		$pg_btn .= "Page: ";

		my ($x, $y) = (1, 0);
		while ($i > 0) {
			if ($pg == $y) {
				$pg_btn .= qq(| <b>$x</b> );
			} else {
				$pg_btn .= qq(| <a href="$link&pg=$y">$x</a> );
			}
			$x++;
			$y += $cf{pg_max};
			$i -= $cf{pg_max};
		}
		$pg_btn .= "|";
	}
	return $pg_btn;
}

#-----------------------------------------------------------
#  クッキー取得
#-----------------------------------------------------------
sub get_cookie {
	my $cook = $cgi->cookie($cf{cookie_id});
	return split(/<>/, $cook);
}

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

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

#-----------------------------------------------------------
#  プルダウン作成 [ 検索条件 ]
#-----------------------------------------------------------
sub make_op {
	my %op;
	my %cond = (1 => 'AND', 0 => 'OR');
	foreach (1,0) {
		if ($in{cond} eq $_) {
			$op{cond} .= qq|<option value="$_" selected>$cond{$_}\n|;
		} else {
			$op{cond} .= qq|<option value="$_">$cond{$_}\n|;
		}
	}
	for ( my $i = 10; $i <= 30; $i += 5 ) {
		if ($in{list} == $i) {
			$op{list} .= qq|<option value="$i" selected>$i件\n|;
		} else {
			$op{list} .= qq|<option value="$i">$i件\n|;
		}
	}
	return %op;
}

