#!/usr/local/bin/perl

#┌─────────────────────────────────
#│ WEB PATIO : patio.cgi - 2011/10/29
#│ Copyright (c) KentWeb
#│ http://www.kent-web.com/
#└─────────────────────────────────

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

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

# データ受理
CGI::Minimal::max_read_size($cf{maxdata});
my $cgi = CGI::Minimal->new;
&error('容量オーバー') if ($cgi->truncated);
my %in = &parse_form($cgi);

# 認証モード
my %au = &authent if ($cf{authkey});

#ssiヘッダ読み込み
our $ssi_header;
my $line;
open(IN,"./ssi/header.html") or &error("open err: ./ssi/header.html");
while ($line = <IN>) {
	$ssi_header .= $line;
}
close(IN);

#文字コード変換
use Encode;
use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
my $dec = Encode::Guess->guess($ssi_header);
if (ref $dec) {
    # utf-8に変換した文字列を取得
    $ssi_header =  Encode::encode('utf8', Encode::decode($dec->name, $ssi_header));
}

#ssiフッタ読み込み
our $ssi_footer;
my $line;
open(IN,"./ssi/footer.html") or &error("open err: ./ssi/footer.html");
while ($line = <IN>) {
	$ssi_footer .= $line;
}
close(IN);

#文字コード変換
use Encode;
use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
my $dec = Encode::Guess->guess($ssi_header);
if (ref $dec) {
    # utf-8に変換した文字列を取得
    $ssi_footer =  Encode::encode('utf8', Encode::decode($dec->name, $ssi_footer));
}

# 処理分岐
if ($in{read}) { &read_log; }
if ($in{edit}) { &pwd_form; }
if ($in{mode} eq 'form') { &form_page; }
if ($in{mode} eq 'find') { &find_page; }
if ($in{mode} eq 'note') { &note_page; }
if ($in{mode} eq 'past') { &past_page; }
&bbs_list;

#-----------------------------------------------------------
#  メニュー部表示
#-----------------------------------------------------------
sub bbs_list {
	# アラーム数定義
	my $alarm = int ( $cf{m_max} * 0.9 );

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

	# スレッド表示
	my ($i,@log);
	open(IN,"$cf{nowfile}") or &error("open err: $cf{nowfile}");
	my $top = <IN>;
	while (<IN>) {
		$i++;
		next if ($i < $pg + 1);
		next if ($i > $pg + $cf{pgmax_now});

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

	# 繰越ボタン作成
	my $page_btn = &make_pgbtn($i,$pg,$cf{pgmax_now});

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

	# テンプレート分割
	my ($head,$loop,$foot);
	if ($tmpl =~ /(.+)<!-- loop_begin -->(.+)<!-- loop_end -->(.+)/s) {
		($head,$loop,$foot) = ($1,$2,$3);
	} else {
		&error("テンプレートが不正です");
	}

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($page_btn);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $page_btn =  Encode::encode('utf8', Encode::decode($dec->name, $page_btn));
        }

	foreach ($head,$foot) {

		# 認証モード
		if ($cf{authkey}) {
			s/!login-name!/$au{name}/g;
		} else {
			s/<!-- auth_begin -->.+?<!-- auth_end -->//sg;
		}

		s/!([a-z]+_cgi)!/$cf{$1}/g;
		s/!bbs_title!/$cf{bbs_title}/g;
		s/!homepage!/$cf{homepage}/g;
		s|!ico:(\w+\.\w+)!|<img src="$cf{iconurl}/$1">|g;
		s/!page-btn!/$page_btn/g;
		s/!ssi_header!/$ssi_header/g;
		s/!ssi_footer!/$ssi_footer/g;
	}

	# 認証クッキー
	if ($cf{authkey} && $in{mode} eq 'login') {
		&set_cookie('CGISESSID',$au{sid});
	}

	# 画面表示
	print "Content-type: text/html\n\n";
	print $head;

	foreach (@log) {
		chomp;
		my ($num,$sub,$res,$nam,$upd,$last,$key,$upl) = split(/<>/);
		my $ukey = $upl ? 1 : 0;

		# 参照カウンタ
		open(NO,"$cf{logdir}/$num.dat");
		my $data = <NO>;
		close(NO);
		my ($cnt) = (split(/:/, $data))[0];

		# 更新日の整形（関）
		my @tmp_upd = split(/\(/,$upd);

                use Encode;
                use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
                my $dec = Encode::Guess->guess($sub);
                if (ref $dec) {
                   # utf-8に変換した文字列を取得
                   $sub =  Encode::encode('utf8', Encode::decode($dec->name, $sub));
                }

                use Encode;
                use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
                my $dec = Encode::Guess->guess($nam);
                if (ref $dec) {
                   # utf-8に変換した文字列を取得
                   $nam =  Encode::encode('utf8', Encode::decode($dec->name, $nam));
                }

                use Encode;
                use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
                my $dec = Encode::Guess->guess($last);
                if (ref $dec) {
                   # utf-8に変換した文字列を取得
                   $last =  Encode::encode('utf8', Encode::decode($dec->name, $last));
                }

		my $tmp = $loop;
		$tmp =~ s/!number!/$num/g;
#		$tmp =~ s/!ico!/&icon($key,$res,$alarm,$upl)/eg;
		$tmp =~ s|!topic!|<a href="$cf{bbs_cgi}?read=$num&ukey=$ukey">$sub</a>|g;
		$tmp =~ s/!name!/$nam/g;
		$tmp =~ s/!res!/$res/g;
#		$tmp =~ s/!count!/$cnt/g;
		$tmp =~ s/!update!/$tmp_upd[0]/g;
		$tmp =~ s/!last!/$last/g;
		print $tmp;
	}

	# フッター
	&footer($foot);
}

#-----------------------------------------------------------
#  フォルダーアイコン
#-----------------------------------------------------------
sub icon {
	my ($key,$res,$alarm,$upl) = @_;

	# アイコン判断
	my $ico;
	if ($key eq '0') { $ico = 0; }
	elsif ($key == 2) { $ico = 2; }
	elsif ($res >= $alarm) { $ico = 'alerm'; }
	elsif ($upl) { $ico = 'image'; }
	else { $ico = 1; }

	return qq|<img src="$cf{iconurl}/$cf{fld_icon}->{$ico}">|;
}

#-----------------------------------------------------------
#  記事閲覧
#-----------------------------------------------------------
sub read_log {
	# クッキー取得
	my ($ck_nam,$ck_eml,$ck_url,$ck_mlo) = &get_cookie;
	$ck_url ||= 'http://';

	# アイコン
	my $smile;
	my @smile = split(/\s+/, $cf{smile});
	foreach (0 .. $#smile) {
		$smile .= qq|<a href="javascript:face('{ico:$_}')"><img src="$cf{iconurl}/$smile[$_]"></a>|;
	}

	# アラーム数定義
	my $alarm = int ( $cf{m_max} * 0.9 );

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

	# スレッド読み込み
	$in{read} =~ s/\D//g;
	my @log;
	open(IN,"$cf{logdir}/$in{read}.cgi") or &error("open err: $in{read}.cgi");
	my $top = <IN>;
	my $par = <IN>;
	my ($no,$sub,$res,$key) = split(/<>/, $top);

	my $i = 0;
	while(<IN>) {
		$i++;
		next if ($i <= $res - $cf{pg_max} - $pg);
		last if ($i > $res - $pg);

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

	# 返信フォーム
	my $resfm = 1;
	if ($key != 1 || $in{log} eq 'past') {
		$resfm = 0;
	}

	# 繰越ボタン作成
	my $page_btn = &make_pgbtn($res, $pg, $cf{pg_max}, "read=$in{read}");

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

	# 画像認証作成
	my ($str_plain,$str_crypt);
	if ($cf{use_captcha} > 0 && $resfm) {
		require $cf{captcha_pl};
		($str_plain, $str_crypt) = cap::make( $cf{captcha_key}, $cf{cap_len} );
	} else {
		$tmpl =~ s/<!-- captcha_begin -->.+<!-- captcha_end -->//s;
	}

	# email表示
	my $op_mlo;
	my @mlo = ('非表示','表示');
	foreach (1,0) {
		if ($ck_mlo eq $_) {
			$op_mlo .= qq|<option value="$_" selected>$mlo[$_]\n|;
		} else {
			$op_mlo .= qq|<option value="$_">$mlo[$_]\n|;
		}
	}

	# 親記事
	my ($no2,$sub,$nam,$eml,$com,$date,$ho,$pw,$url,$mlo,$myid,$tim,$up1,$up2,$up3) = split(/<>/, $par);
	$nam = qq|<a href="mailto:$eml">$nam</a>| if ($eml && $mlo);
	$url &&= qq|<a href="$url" target="_blank">$url</a>|;
	$com =~ s/\{ico:(\d+)\}/<img src="$cf{iconurl}\/$smile[$1]">/g;

	# 画像
	$com = &image($com,$tim,$up1,$up2,$up3);

	# フォーム用件名
	my $resub = $sub =~ /^Re:/ ? $sub : "Re: $sub";

	#記事番号の整形
	my $tmp_no = "[" . $no . "]";

	#URLにリンク作成（関）
	my $comment_tmp = $com;
	$comment_tmp =~ s/(http\:\/\/[\w\.\:\/\+\-\?\~=&%]+)/<a href=\"$1\">$1<\/a>/g;

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($sub);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $sub =  Encode::encode('utf8', Encode::decode($dec->name, $sub));
        }

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($nam);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $nam =  Encode::encode('utf8', Encode::decode($dec->name, $nam));
        }

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($comment_tmp);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $comment_tmp =  Encode::encode('utf8', Encode::decode($dec->name, $comment_tmp));
        }

	# 文字置き換え
	$tmpl =~	s/!ssi_header!/$ssi_header/g;
	$tmpl =~	s/!ssi_footer!/$ssi_footer/g;
	$tmpl =~ s/!([a-z]+_cgi)!/$cf{$1}/g;
	$tmpl =~ s/!ico!/&icon($key,$res,$alarm,$in{ukey})/eg;
	$tmpl =~ s/!number!/$tmp_no/g;
	$tmpl =~ s/!sub!/$sub/g;
	$tmpl =~ s/!date!/$date/g;
	$tmpl =~ s/!name!/$nam/g;
	$tmpl =~ s/!url!/$url/g;
	$tmpl =~ s/!comment!/$comment_tmp/g;
	$tmpl =~ s|!ico_edit!|<a href="$cf{bbs_cgi}?edit=$in{read}&no=0"><img src="$cf{iconurl}/pg_edit.gif" alt="記事編集"></a>|g;
	$tmpl =~ s/!page_btn!/$page_btn/g;
	$tmpl =~ s/!res!/$in{read}/g;

	# 認証モード
	$tmpl =~ s/<!-- id -->/[ID: $myid]/g if ($cf{authkey} && $myid);

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($resub);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $resub =  Encode::encode('utf8', Encode::decode($dec->name, $resub));
        }

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($ck_nam);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $ck_nam =  Encode::encode('utf8', Encode::decode($dec->name, $ck_nam));
        }

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($op_mlo);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $op_mlo =  Encode::encode('utf8', Encode::decode($dec->name, $op_mlo));
        }

	# 返信フォーム/編集ボタン
	if (!$resfm) {
		$tmpl =~ s/<!-- resform_begin -->.+<!-- resform_end -->//sg;
		$tmpl =~ s/<!-- edit_begin -->.+?<!-- edit_end -->//sg;
	} else {
		$tmpl =~ s/!str_crypt!/$str_crypt/g;
		$tmpl =~ s/!fm_sub!/$resub/g;
		$tmpl =~ s/!fm_name!/$ck_nam/g;
		$tmpl =~ s/!fm_email!/$ck_eml/g;
		$tmpl =~ s/!fm_url!/$ck_url/g;
		$tmpl =~ s/!smile!/$smile/g;
		$tmpl =~ s/<!-- op_mlo -->/$op_mlo/g;
	}

	# テンプレート分割
	my ($head,$loop,$foot);
	if ($tmpl =~ /(.+)<!-- loop_begin -->(.+)<!-- loop_end -->(.+)/s) {
		($head,$loop,$foot) = ($1,$2,$3);
	} else {
		&error("テンプレートが不正です");
	}

	# ヘッダ表示
	print "Content-type: text/html\n\n";
	print $head;

	# レス記事
	foreach (@log) {
		my ($no,$sub,$nam,$eml,$com,$date,$ho,$pw,$url,$mlo,$myid,$tim,$up1,$up2,$up3) = split(/<>/);
		$nam = qq|<a href="mailto:$eml">$nam</a>| if ($eml && $mlo);
		$url &&= qq|<a href="$url" target="_blank">$url</a>|;
		$com =~ s/\{ico:(\d+)\}/<img src="$cf{iconurl}\/$smile[$1]">/g;

		# 画像
		$com = &image($com,$tim,$up1,$up2,$up3);

		#URLにリンク作成（関）
		my $comment_tmp = $com;
		$comment_tmp =~ s/(http\:\/\/[\w\.\:\/\+\-\?\~=&%]+)/<a href=\"$1\">$1<\/a>/g;

		use Encode;
        	use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        	my $dec = Encode::Guess->guess($nam);
        	if (ref $dec) {
           		# utf-8に変換した文字列を取得
           		$nam =  Encode::encode('utf8', Encode::decode($dec->name, $nam));
        	}

		use Encode;
        	use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        	my $dec = Encode::Guess->guess($sub);
        	if (ref $dec) {
           		# utf-8に変換した文字列を取得
           		$sub =  Encode::encode('utf8', Encode::decode($dec->name, $sub));
        	}

		use Encode;
        	use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        	my $dec = Encode::Guess->guess($comment_tmp);
        	if (ref $dec) {
           		# utf-8に変換した文字列を取得
           		$comment_tmp =  Encode::encode('utf8', Encode::decode($dec->name, $comment_tmp));
        	}

		my $tmp = $loop;
		$tmp =~ s|!ico:(\w+\.\w+)!|<img src="$cf{iconurl}/$1">|g;
		$tmp =~ s/!res_sub!/$sub/g;
		$tmp =~ s/!res_date!/$date/g;
		$tmp =~ s/!res_name!/$nam/g;
		$tmp =~ s/!res_url!/$url/g;
		$tmp =~ s/!res_com!/$comment_tmp/g;
		$tmp =~ s|!res_ico_edit!|<a href="$cf{bbs_cgi}?edit=$in{read}&no=$no"><img src="$cf{iconurl}/pg_edit.gif" alt="記事編集"></a>|g;
		print $tmp;
	}

	# カウントアップ
	&count_up;

	# フッター
	&footer($foot);
}

#-----------------------------------------------------------
#  認証フォーム
#-----------------------------------------------------------
sub pwd_form {
	# 汚染チェック
	$in{edit} =~ s/\D//g;
	$in{no} =~ s/\D//g;

	# 記事
	my ($name,$pwd);
	open(IN,"$cf{logdir}/$in{edit}.cgi") or &error("open err: $in{edit}.cgi");
	my $top = <IN>;
	while(<IN>) {
		my ($no,$sub,$nam,$eml,$com,$dat,$ho,$pw,$url,$mlo,$myid,$tim,$upl1,$upl2,$upl3) = split(/<>/);

		if ($in{no} == $no) {
			$name = $nam;
			$pwd = $pw;
			last;
		}
	}
	close(IN);

	# パスワード未設定
	&error("この記事はパスワード未設定のため編集できません") if ($pwd eq '');

	# 処理選択オプション
	my $op_job = qq|<option value="edit" selected>記事を編集\n|;
	if ($in{no} == 0) {
		$op_job .= qq|<option value="lock">スレッドをロック\n|;
	} else {
		$op_job .= qq|<option value="dele">記事を削除\n|;
	}

	# 記事情報データ分解
	my ($no,$sub,$res,$key) = split(/<>/, $top);

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

	# 文字置換
	$tmpl =~	s/!ssi_header!/$ssi_header/g;
	$tmpl =~	s/!ssi_footer!/$ssi_footer/g;
	$tmpl =~ s/!sub!/$sub/g;
	$tmpl =~ s/!name!/$name/g;
	$tmpl =~ s/!art!/$in{edit}/g;
	$tmpl =~ s/!no!/$in{no}/g;
	$tmpl =~ s/!([a-z]+_cgi)!/$cf{$1}/g;
	$tmpl =~ s|!ico:(\w+\.\w+)!|<img src="$cf{iconurl}/$1">|g;
	$tmpl =~ s/<!-- op_job -->/$op_job/g;


	# 画面表示
	print "Content-type: text/html\n\n";
	print $tmpl;
	exit;
}

#-----------------------------------------------------------
#  留意事項表示
#-----------------------------------------------------------
sub note_page {
	# テンプレート読み込み
	open(IN,"$cf{tmpldir}/note.html") or &error("open err: note.html");
	my $tmpl = join('', <IN>);
	close(IN);

	# 文字置換
	$tmpl =~ s/!maxdata!/$cf{maxdata}バイト/g;
	$tmpl =~ s/!max_w!/$cf{max_img_w}/g;
	$tmpl =~ s/!max_h!/$cf{max_img_h}/g;

	# 画面表示
	print "Content-type: text/html\n\n";
	print $tmpl;
	exit;
}

#-----------------------------------------------------------
#  画像表示
#-----------------------------------------------------------
sub image {
	my ($com,$fnam,$up1,$up2,$up3) = @_;
	my %img = (1 => $up1, 2 => $up2, 3 => $up3);

	my $img;
	foreach my $i (1 .. 3) {
		my ($ex,$w,$h) = split(/,/, $img{$i});
		if ($ex) {
			($w,$h) = &resize($w,$h);
			my $pic = -e "$cf{uplurl}/$fnam-s-$i$ex" ? "$fnam-s-$i$ex" : "$fnam-$i$ex";
			$img .= qq|<div class="image"><img src="$cf{uplurl}/$pic" width="$w" height="$h" hspace="2"></div>|;
		}
	}
	if ($img) {
		return "$com$img";
	} else {
		return $com;
	}
}

#-----------------------------------------------------------
#  投稿フォーム
#-----------------------------------------------------------
sub form_page {
	# クッキー取得
	my ($ck_nam,$ck_eml,$ck_url,$ck_mlo) = &get_cookie;
	$ck_url ||= 'http://';

	# アイコン
	my $smile;
	my @smile = split(/\s+/, $cf{smile});
	foreach (0 .. $#smile) {
		$smile .= qq|<a href="javascript:face('{ico:$_}')"><img src="$cf{iconurl}/$smile[$_]"></a>|;
	}

	# テンプレート読み込み
	open(IN,"$cf{tmpldir}/form.html") or &error("open err: form.html");
	my $tmpl = join('', <IN>);
	close(IN);
	$tmpl =~	s/!ssi_header!/$ssi_header/g;
	$tmpl =~	s/!ssi_footer!/$ssi_footer/g;

	# email表示
	my $op_mlo;
	my @mlo = ('非表示','表示');
	foreach (1,0) {
		if ($ck_mlo eq $_) {
			$op_mlo .= qq|<option value="$_" selected>$mlo[$_]\n|;
		} else {
			$op_mlo .= qq|<option value="$_">$mlo[$_]\n|;
		}
	}

	# 画像認証作成
	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} );
	} else {
		$tmpl =~ s/<!-- captcha_begin -->.+<!-- captcha_end -->//s;
	}

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($op_mlo);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $op_mlo =  Encode::encode('utf8', Encode::decode($dec->name, $op_mlo));
        }

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($ck_nam);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $ck_nam =  Encode::encode('utf8', Encode::decode($dec->name, $ck_nam));
        }

	# 文字置換
	$tmpl =~ s/!([a-z]+_cgi)!/$cf{$1}/g;
	$tmpl =~ s/!ico:(\w+\.\w+)!/<img src="$cf{iconurl}\/$1">/g;
	$tmpl =~ s/!str_crypt!/$str_crypt/g;
	$tmpl =~ s/!name!/$ck_nam/g;
	$tmpl =~ s/!email!/$ck_eml/g;
	$tmpl =~ s/!url!/$ck_url/g;
	$tmpl =~ s/!smile!/$smile/g;
	$tmpl =~ s/<!-- op_mlo -->/$op_mlo/g;

	# 画面表示
	print "Content-type: text/html\n\n";
	print $tmpl;
	exit;
}

#-----------------------------------------------------------
#  検索画面
#-----------------------------------------------------------
sub find_page {
	# テンプレート読み込み
	open(IN,"$cf{tmpldir}/find.html") or &error("open err: find.html");
	my $tmpl = join('', <IN>);
	close(IN);

	# 条件
	if ($in{cond} eq '') { $in{cond} = 1; }
	my $op_cond;
	my %cond = (1 => 'AND', 0 => 'OR');
	foreach (1,0) {
		if ($in{cond} == $_) {
			$op_cond .= qq|<option value="$_" selected>$cond{$_}\n|;
		} else {
			$op_cond .= qq|<option value="$_">$cond{$_}\n|;
		}
	}
	# 範囲
	$in{area} ||= 1;
	my %area = (1 => '現行ログ', 2 => '過去ログ');
	my $area;
	foreach (1,2) {
		if ($in{area} == $_) {
			$area .= qq|<input type="radio" name="area" value="$_" checked>$area{$_}\n|;
		} else {
			$area .= qq|<input type="radio" name="area" value="$_">$area{$_}\n|;
		}
	}

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($area);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $area =  Encode::encode('utf8', Encode::decode($dec->name, $area));
        }

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($in{word});
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $in{word} =  Encode::encode('utf8', Encode::decode($dec->name, $in{word}));
        }

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($cf{$1});
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $cf{$1} =  Encode::encode('utf8', Encode::decode($dec->name, $cf{$1}));
        }


	# 文字置換
	$tmpl =~	s/!ssi_header!/$ssi_header/g;
	$tmpl =~	s/!ssi_footer!/$ssi_footer/g;
	$tmpl =~ s/!([a-z]+_cgi)!/$cf{$1}/g;
	$tmpl =~ s/!ico:(\w+\.\w+)!/<img src="$cf{iconurl}\/$1">/g;
	$tmpl =~ s/<!-- op_cond -->/$op_cond/g;
	$tmpl =~ s/!area!/$area/g;
	$tmpl =~ s/!word!/$in{word}/g;

	# 検索実行
	if ($in{word} ne '') {

		my ($head,$loop,$foot);
		if ($tmpl =~ /(.+)<!-- search_begin -->(.+)<!-- search_end -->(.+)/s) {
			($head,$loop,$foot) = ($1,$2,$3);
		} else {
			&error("テンプレートが不正です$tmpl");
		}

		# 画面表示
		print "Content-type: text/html\n\n";
		print $head;
		&search($loop);
		print $foot;
		exit;

	# 検索前
	} else {

		$tmpl =~ s/<!-- search_begin -->.+<!-- search_end -->//s;

		# 画面表示
		print "Content-type: text/html\n\n";
		print $tmpl;
		exit;
	}
}

#-----------------------------------------------------------
#  検索実行
#-----------------------------------------------------------
sub search {
	my $loop = shift;
	$loop =~ /(.+)<!-- loop_begin -->(.+)<!-- loop_end -->(.+)/s;
	my ($head,$loop,$foot) = ($1,$2,$3);

	# キーワード
	Jcode::convert(\$in{word}, 'sjis');
	$in{word} =~ s/　/ /g;
	my @wd = split(/\s+/, $in{word});

	# 対象範囲/引数
	my ($idx,$param);
	if ($in{area} == 1) {
		$idx = $cf{nowfile};
	} else {
		$idx = $cf{pastfile};
		$param = "&log=past";
	}

	# indexオープン
	my @find;
	open(IN,"$idx") or &error("open err: $idx");
	my $top = <IN>;
	while(<IN>) {
		my ($num,$sub,$res,$nam,$upd,$last,$key,$upl) = split(/<>/);

		# 各スレッド読み込み
		open(LOG,"$cf{logdir}/$num.cgi");
		my $log = join('', <LOG>);
		close(LOG);

		# スレッド内検索
		my $flg;
		foreach my $wd (@wd) {
			if (index($log, $wd) >= 0) {
				$flg++;
				if ($in{cond} == 0) { last; }
			} else {
				if ($in{cond} == 1) { $flg = 0; last; }
			}
		}
		if ($flg) { push(@find,$_); }
	}
	close(IN);

	# ヒット件数
	my $hit = @find;
	$head =~ s/!hit!/$hit/g;
	$foot =~ s/!hit!/$hit/g;

	# アラーム数定義
	my $alarm = int ( $cf{m_max} * 0.9 );

	# 結果表示
	print $head;
	foreach (@find) {
		my ($num,$sub,$res,$nam,$upd,$last,$key,$upl) = split(/<>/);
		my $ukey = $upl ? 1 : 0;

		# 更新日の整形（関）
		my @tmp_upd = split(/\(/,$upd);

        use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($nam);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $nam =  Encode::encode('utf8', Encode::decode($dec->name, $nam));
        }

use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($sub);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $sub =  Encode::encode('utf8', Encode::decode($dec->name, $sub));
        }

use Encode;
        use Encode::Guess qw/ascii utf8 euc-jp shiftjis 7bit-jis/;
        my $dec = Encode::Guess->guess($last);
        if (ref $dec) {
           # utf-8に変換した文字列を取得
           $last =  Encode::encode('utf8', Encode::decode($dec->name, $last));
        }
		my $tmp = $loop;
		$tmp =~ s/!number!/$num/g;
#		$tmp =~ s/!icon!/&icon($key,$res,$alarm,$upl)/eg;
		$tmp =~ s|!sub!|<a href="$cf{bbs_cgi}?read=$num&ukey=$ukey$param">$sub</a>|g;
		$tmp =~ s/!name!/$nam/g;
		$tmp =~ s/!res!/$res/g;
		$tmp =~ s/!update!/$tmp_upd[0]/g;
		$tmp =~ s/!topic!/$sub/g;
		$tmp =~ s/!last!/$last/g;
		print $tmp;
	}
	print $foot;
}

#-----------------------------------------------------------
#  過去ログページ
#-----------------------------------------------------------
sub past_page {
	# ページ数
	my $pg = $in{pg} || 0;

	# スレッド表示
	my ($i,@log);
	open(IN,"$cf{pastfile}") or &error("open err: $cf{pastfile}");
	while (<IN>) {
		$i++;
		next if ($i < $pg + 1);
		next if ($i > $pg + $cf{pgmax_past});

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

	# 繰越ボタン作成
	my $page_btn = &make_pgbtn($i, $pg, $cf{pgmax_past}, "mode=past");

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

	# 文字置換
	$tmpl =~ s/!([a-z]+_cgi)!/$cf{$1}/g;
	$tmpl =~ s/!ico:(\w+\.\w+)!/<img src="$cf{iconurl}\/$1">/g;
	$tmpl =~ s/!page-btn!/$page_btn/g;
	$tmpl =~ s/!ssi_header!/$ssi_header/g;
	$tmpl =~ s/!ssi_footer!/$ssi_footer/g;


	my ($head,$loop,$foot);
	if ($tmpl =~ /(.+)<!-- loop_begin -->(.+)<!-- loop_end -->(.+)/s) {
		($head,$loop,$foot) = ($1,$2,$3);
	} else {
		&error("テンプレートが不正です");
	}

	# 画面表示
	print "Content-type: text/html\n\n";
	print $head;

	foreach (@log) {
		my ($num,$sub,$res,$nam,$upd,$last,$key,$upl) = split(/<>/);

		# 更新日の整形（関）
		my @tmp_upd = split(/\(/,$upd);

		my $tmp = $loop;
		$tmp =~ s/!number!/$num/g;
#		$tmp =~ s|!icon!|<img src="$cf{iconurl}/fld_nor.gif">|;
		$tmp =~ s|!sub!|<a href="$cf{bbs_cgi}?read=$num&log=past">$sub</a>|g;
		$tmp =~ s/!name!/$nam/g;
		$tmp =~ s/!res!/$res/g;
		$tmp =~ s/!update!/$tmp_upd[0]/g;
		print $tmp;
	}

	# フッター
	&footer($foot);
}

#-----------------------------------------------------------
#  フッター
#-----------------------------------------------------------
sub footer {
	my $foot = shift;

	# 著作権表記（削除・改変禁止）
#	my $copy = <<EOM;
#<p style="margin-top:2.5em;text-align:center;font-family:Verdana,Arial,Helvetica;font-size:10px;">
#- <a href="http://www.kent-web.com/" target="_top">WEB PATIO</a> -
#</p>
#EOM

#	if ($foot =~ /(.+)(<\/body[^>]*>.*)/si) {
#		print "$1$copy$2\n";
#	} else {
#		print "$foot$copy\n";
#		print "</body></html>\n";
#	}

	print "$foot\n";

	exit;
}

#-----------------------------------------------------------
#  繰越ボタン作成
#-----------------------------------------------------------
sub make_pgbtn {
	my ($i, $pg, $max, $param) = @_;
	$max ||= 10;

	# 引数
	$param &&= "&$param";

	# ページ繰越定義
	my $next = $pg + $max;
	my $back = $pg - $max;

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

		my ($x, $y) = (1, 0);
		while ($i > 0) {
			if ($pg == $y) {
				$pg_btn .= qq(| <b>$x</b> );
			} else {
				$pg_btn .= qq(| <a href="$cf{bbs_cgi}?pg=$y$param">$x</a> );
			}
			$x++;
			$y += $max;
			$i -= $max;
		}
		return qq!<p class="pg-btn">$pg_btn|</p>!;
	} else {
		return;
	}
}

#-----------------------------------------------------------
#  カウントアップ
#-----------------------------------------------------------
sub count_up {
	# IP取得
	my $addr = $ENV{REMOTE_ADDR};

	# カウントデータオープン
	open(DAT,"+< $cf{logdir}/$in{read}.dat") or &error("open err: $in{read}.dat");
	eval "flock(DAT, 2);";
	my $data = <DAT>;
	my ($cnt,$ip) = split(/:/, $data);

	# IPチェック
	if ($addr ne $ip) {
		$cnt++;
		seek(DAT, 0, 0);
		print DAT "$cnt:$addr";
		truncate(DAT, tell(DAT));
	}
	close(DAT);
}

#-----------------------------------------------------------
#  認証モード
#-----------------------------------------------------------
sub authent {
	# セッションモジュール取り込み
	require $cf{session_pl};

	# ログイン
	if ($in{mode} eq 'login') {
		# 入力チェック
		if ($in{id} eq '' || $in{pw} eq '') {
			&error("IDまたはパスワードが未入力です");
		}
		# セッション作成
		&make_ses($in{id},$in{pw},$cf{memfile},$cf{sesdir},$cf{authtime});

	# ログオフ
	} elsif ($in{mode} eq 'logoff') {
		# セッション削除
		&del_ses($cf{sesdir});

		# 入室画面
		&enter_form('cook_del');

	# 入室画面
	} elsif ($in{mode} eq 'enter') {
		&enter_form;

	# セッション管理
	} else {
		&session($cf{sesdir},$cf{bbs_cgi});
	}
}

#-----------------------------------------------------------
#  入室画面
#-----------------------------------------------------------
sub enter_form {
	my $ck = shift;

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

	# 文字置換
	$tmpl =~ s/!bbs_cgi!/$cf{bbs_cgi}/g;

	# クッキー排除
	if ($ck eq 'cook_del') {
		&set_cookie('CGISESSID','','del');
	}

	# 画面表示
	print "Content-type: text/html\n\n";
	print $tmpl;
	exit;
}

#-----------------------------------------------------------
#  crypt照合
#-----------------------------------------------------------
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 get_cookie {
	# クッキー取得
	my $cook = $ENV{HTTP_COOKIE};

	# 該当IDを取り出す
	my %cook;
	foreach ( split(/;/, $cook) ) {
		my ($key,$val) = split(/=/);
		$key =~ s/\s//g;
		$cook{$key} = $val;
	}

	# URLデコード
	my @cook;
	foreach ( split(/<>/, $cook{$cf{cookie_id}}) ) {
		s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		s/[&"'<>]//g;

		push(@cook,$_);
	}
	return @cook;
}

#-----------------------------------------------------------
#  クッキー発行
#-----------------------------------------------------------
sub set_cookie {
	my ($key,$val,$del) = @_;

	# 時間定義
	my $gtime = $del eq 'del' ? time - 365*24*60*60 : time + 60*24*60*60;

	my ($sec,$min,$hour,$mday,$mon,$year,$wday,undef,undef) = gmtime($gtime);
	my @mon  = qw|Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec|;
	my @week = qw|Sun Mon Tue Wed Thu Fri Sat|;

	# 時刻フォーマット
	my $gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT",
				$week[$wday],$mday,$mon[$mon],$year+1900,$hour,$min,$sec);

	print "Set-Cookie: $key=$val; expires=$gmt\n";
}

