#!/usr/local/bin/perl

# FlasH BBS Pro version 1.41
#
# Script written by Shigeto Nakazawa.(1997/1/17)
# < http://www7.big.or.jp/~jawa/ >
# This script is free.

# //////////////////////////////////////////////////////////
# //      オプションの設定変更はここから始まります。      //
# //////////////////////////////////////////////////////////

# ----------------------------------------------------------
# 記事の最大登録数等を設定できます。
# ----------------------------------------------------------

$max_size = 99 *1024;           # 記事削除開始記録ファイルサイズ（約nバイト 最低 1500)
$max_tree = 200;                # リストに表示するツリーの数です。
$max_msg = 8000;                # 投稿を受理する最大文字数（半角 n 文字）
$new_kiji = 10;                 # 最新情報に[NEW]をつける数

# ----------------------------------------------------------
# この掲示板の管理者（あなた）の情報です。
# ----------------------------------------------------------


$admin_name = 'ABS Systems';           # あなたの名前(ハンドルネーム)を書きます。
$admin_email = 'm-y@abs-systems.jp';              # あなたのメールアドレスを書きます。

# ----------------------------------------------------------
# この掲示板のカスタマイズ項目です。
# ----------------------------------------------------------

$title = "ABS Systems掲示板";     # 掲示板のタイトル
$body_text    = '#ffffff';          # <BODY> タグの設定
$body_link    = '#ff00FF';          # リンクの色
$body_alink   = '#FF00ff';          # クリック中のリンクの色
$body_vlink   = '#ffff00';          # 既にクリック済みのリンクの色
$body_bgcolor = '#004020';          # 背景の色
#$body_back    = 'back.gif';                 # 背景画像

$backurl = "http://ans-systems.jp/";                   # 帰りの URL
$date = "year/mon/day hour:min";    # 時間表示フォーマット
$date_type = 1;                     # 一桁のとき二桁に修正するか？
                                    # 0:しない 1:する（時分秒） 2:する（全て）

$em_color           = "#FFffff";    # 強調色の色（数字等）
$kiji_title_color   = "#ff0020";    # 記事のタイトルの色
$kiji_title_bgcolor = "#202020";    # 記事のタイトルの背景色
$form_bgcolor       = "#202020";    # 記事投稿フォームの背景色
$res_color          = "#ffe0e0";    # 記事につくレスの色

$gif_allnews  = 'all_news.gif';     # 一括購読用の GIF IMAGE
$gif_news     = 'news.gif';         # 標準購読用の GIF IMAGE
$gif_new_news = 'new_news.gif';     # 最新記事用の GIF IMAGE
$gif_space    = 'space.gif';        # 透明      の GIF IMAGE（ダミー画像）

$gif_width = 20;                    # GIF IMAGE の横幅
$gif_height = 14;                   # GIF IMAGE の縦幅
$tree_width = 30;                   # Tree Width（ツリーがずれます？）

$html_title=<<"_EOF_";              # HTML 文の設定（タイトル）
<CENTER><FONT COLOR="red"><B><I>
<img SRC="bbstitle.gif"  align=CENTER>
</I></B></FONT></CENTER><P>
_EOF_
# ↑ この _EOF_ は必要です。
$html_info=<<"_EOF_";               # HTML 文の設定（案内）
<CENTER>

<TABLE BORDER="2" WIDTH="80%" CELLSPACING="0" CELLPADDING="4">
<TR><TD BGCOLOR="#FFFFFF">
<CENTER>
<br>
<FONT COLOR="red" size="+2">くれぐれも荒らさないように！</font>
<BR>
<FONT SIZE=-1>
<LI><BR>

</FONT>
</CENTER>
</TR></TD></TABLE>

</CENTER>
<P>
_EOF_
# ↑ この _EOF_ は必要です。

# ----------------------------------------------------------
# クッキー、ファイル、セキュリティー関連
# 書き換える必要がある場合を除いては変更してはいけません。
# ----------------------------------------------------------

$base_url = "";     # ここにこのCGIの正確な URL (http://〜) を書いておくと
                    # 他サイトから不正に投稿されたものを拒否できます。
$cookie_name = 'fbbspro';           # クッキーのＩＤ
$jcode     = './jcode.pl';          # jcode.pl のある場所   (URLじゃないよ)
$logfile   = './flashbbs.log';      # 記録用ファイル        (URLじゃないよ)
$countfile = './flashbbs.cnt';      # カウンタファイル      (URLじゃないよ)
$lock1     = './fbbs1.lock';        # 鍵ファイル(1)         (URLじゃないよ)
$lock2     = './fbbs2.lock';        # 鍵ファイル(2)         (URLじゃないよ)
$lock_flag = 1;                     # 鍵ファイルの 1:使用 0:不使用

# //////////////////////////////////////////////////////////
# //         オプションの設定変更はここまでです。         //
# //////////////////////////////////////////////////////////

# [ メイン処理 ]

# $ID = $FORM{'id'};
&check_code;
&read_form;
&get_cookie;
&check_cookie;
@logs = &read_file($logfile);
if ($FORM{'md'} eq 'reg') { &regist; }
elsif ($FORM{'md'} eq 'del') { &delete; }
elsif ($FORM{'md'} eq 'viw') { &view; }
elsif ($FORM{'md'} eq 'new') {
    &html_header("新規投稿");print"<HR SIZE=1>\n";&html_form('root');
}
elsif ($FORM{'md'} eq 'set') { &set; }
elsif ($FORM{'md'} eq 'num') { &number; }
else { &ichiran; }
&html_footer;
exit 0;

# [ ヘッダー部分表示 ]
#

sub html_header {
    local($sub_title) = $_[0];
    local($font_size) = ($COOKIE{'font'} > 0) + 3;
    print "Content-type: text/html\n\n";
    print<<"_EOF_";
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=$charset_code">
<META NAME="KeyWord" CONTENT="FlasH BBS Pro">
<TITLE>$title [$sub_title]</TITLE>
</HEAD>
<BODY TEXT=$body_text  LINK=$body_link ALINK=$body_alink VLINK=$body_vlink BGCOLOR=$body_bgcolor BACKGROUND=$body_back>
<BASEFONT SIZE=$font_size><TT>
$html_title
<CENTER>
[
<A HREF=$backurl>ＡＢＳ Ｓｙｓｔｅｍｓの部屋に戻る</A> / <A HREF="./flashbbs.htm">利用方法</A> / <A HREF="flashbbs.cgi?id=$ID">一覧表\示</A> / <A HREF="flashbbs.cgi?id=$ID&md=num">最新記事</A> / <A HREF="flashbbs.cgi?id=$ID&md=new">新規投稿</A> / <A HREF="fbeditor.cgi?id=$ID">秘密</A>
]
</CENTER><P>
_EOF_
}

# [ 著作権等の表示（必ず著作権を表示すること） ]
#

sub html_footer {
    print<<"_EOF_";
<HR SIZE=1>
<DIV ALIGN="right"><TT>
<!-- 管理者表\示 -->
掲示板管理者 <A HREF="mailto:$admin_email">$admin_name</A> :
<!-- 著作権表\示 （必ず表\示してください。） -->
FlasH BBS Pro v1.41 [<A HREF="http://www7.big.or.jp/~jawa/">Shigeto Nakazawa</A>]
</TT></DIV>
</TT></BASEFONT>
</BODY></HTML>
_EOF_
}

# [ 一覧表示 ]
#

sub ichiran {
    &set_cookie;
    &html_header("一覧表\示");
    $count = (&read_file($countfile))[0];
    $tree = $COOKIE{'tree'};
    if ($tree > @logs) { $tree = 0; }
    if (!$tree) { $tree = 0; }
    $tree = int($tree/$max_tree)*$max_tree;
    print<<"_EOF_";
$html_info
<CENTER>
<TABLE>
<FORM ACTION="./flashbbs.cgi">
<INPUT TYPE="hidden" NAME="id" VALUE="$ID">
<INPUT TYPE="hidden" NAME="md" VALUE="new">
<TH><INPUT TYPE="submit" VALUE="新規投稿">　</TH>
</FORM>
<FORM ACTION="./flashbbs.cgi" METHOD="post">
<INPUT TYPE="hidden" NAME="id" VALUE="$ID">
<TH>
<SELECT NAME="font">
_EOF_
    if (!$COOKIE{'font'}) {
        print"<OPTION VALUE=\"0\" SELECTED>標準文字の\n";
        print"<OPTION VALUE=\"1\">拡大文字の\n";
    } else {
        print"<OPTION VALUE=\"0\">標準文字の\n";
        print"<OPTION VALUE=\"1\" SELECTED>拡大文字の\n";
    }
    print<<"_EOF_";
</SELECT>
</TH><TH>
<SELECT NAME="sort">
_EOF_
    if (!$COOKIE{'sort'}) {
        print"<OPTION VALUE=\"0\" SELECTED>レス順で\n";
        print"<OPTION VALUE=\"1\">登録順で\n";
    } else {
        print"<OPTION VALUE=\"0\">レス順で\n";
        print"<OPTION VALUE=\"1\" SELECTED>登録順で\n";
        @logs = reverse(sort(@logs));
    }
    print<<"_EOF_";
</SELECT>
</TH><TH>
<SELECT NAME="tree">
_EOF_
    for ($i=0;$i<@logs;$i+=$max_tree) {
        $j=$i/$max_tree+1;
        if ($tree == $i) {
            print" <OPTION VALUE=\"$i\" SELECTED>$j ページを\n";
        } else {
            print" <OPTION VALUE=\"$i\">$j ページを\n";
        }
    }
    print<<"_EOF_";
</SELECT>
</TH><TH>
<INPUT TYPE="submit" VALUE="表\示する">
</TH>
</FORM>
</TABLE>
</CENTER>
_EOF_
    print"<PRE>\n";
    $end_tree = $tree + $max_tree;
    if ($end_tree > @logs) { $end_tree = @logs; }
    for ($i=$tree;$i<$end_tree;$i++) {
        print"<HR SIZE=1>";
        @datas = &divide_log($logs[$i]);
        foreach (@datas) {
            local($no,$res,$lx,$tn,$title,$name,$email,$date,$act) = &divide_data($_);
            if ($res eq 'root') {
                print "<A HREF=\"flashbbs.cgi?id=$ID&md=set&tn=$tn\"><IMG SRC=\"$gif_allnews\" WIDTH=$gif_width HEIGHT=$gif_height BORDER=0></A>";
            } else {
                local($space_width) = $gif_width+$tree_width*$lx;
                print "<IMG SRC=\"$gif_space\" WIDTH=$space_width HEIGHT=$gif_height>";
            }
            print "<A HREF=\"flashbbs.cgi?id=$ID&md=viw&no=$no&tn=$tn\">";
            if ($no > $count - $new_kiji) {
                print "<IMG SRC=\"$gif_new_news\" WIDTH=$gif_width HEIGHT=$gif_height BORDER=0>";
            } else {
                print "<IMG SRC=\"$gif_news\" WIDTH=$gif_width HEIGHT=$gif_height BORDER=0>";
            }
            print "$title</A> : ";
            if ($COOKIE{'name'} eq $name) {
                print "<B>$name</B>";
            } else { print $name; }
            print " <FONT COLOR=\"$em_color\">($date)</FONT>\n";
        }
    }
    print"</PRE>\n";
}

# [ 個別で記事の内容を表示する ]
#

sub view {
    &html_header("記事($FORM{'no'})");
    @kiji_datas = &divide_log(&search_no2data($FORM{'tn'},@logs));
    $kiji_data = &search_no2data($FORM{'no'},@kiji_datas);

    print"<HR SIZE=1>\n";
    &kiji_view($kiji_data);
    print"<HR SIZE=1>\n";
    local($no,$rq_res,$lx,$tn,$title,$name,$email,$date,$rq_act,$file_pwd,$rhost,$ipad,$comment) = &divide_data($kiji_data);
    foreach (@kiji_datas) {
        local($no,$res,$lx,$tn,$title,$name,$email,$date,$act,$pwd,$rhost,$ipad,$comment) = &divide_data($_);
        if ($rq_res == $no) {
            $parent = "▲ <A HREF=\"flashbbs.cgi?id=$ID&md=viw&no=$no&tn=$FORM{'tn'}\">$title</A> : $name<FONT COLOR=\"$em_color\">($date)</FONT>\n";
        }
        if (($res == $FORM{'no'}) && ($res ne 'root')) {
            $children .= "▼ <A HREF=\"flashbbs.cgi?id=$ID&md=viw&no=$no&tn=$FORM{'tn'}\">$title</A> : $name<FONT COLOR=\"$em_color\">($date)</FONT>\n";
        }
    }
    if ($rq_res eq 'root') { $parent = "<FONT COLOR=\"$em_color\">この記事がルート記事です。</FONT>"; }
    elsif (!$parent) { $parent = "<FONT COLOR=\"$em_color\">元になった記事はみつかりませんでした。</FONT>"; }
    if (!$children) { $children = "<FONT COLOR=\"$em_color\">返事はありません。</FONT>"; }
    print<<"_EOF_";
<PRE>[この記事の元になった記事です。 ]<P>
$parent
<HR SIZE=1>
[この記事に対する返事です。]<P>
$children</PRE>

<HR SIZE=1>
<CENTER>この記事に返事を出す場合は下の投稿フォームに書き込んで下さい。</CENTER>
_EOF_
    if ($rq_act > 6) {
        print "<P><CENTER>残念ながら返事は書けないようです。</CENTER>\n";
        return 0;
    }
    if ($title =~ /^Re\[(\d+)\]:/){
        local($ct) = $1;
        $ct++;
        $title =~ s/Re\[\d+\]:/Re\[$ct\]:/;
    } elsif ($title =~ /^Re:/){
        $title =~ s/Re:/Re\[2\]:/;
    } else {
        $title = "Re:$title";
    }
    $comment = "<BR>$comment";
    $comment =~ s/<BR>((&gt;)+)/\n$1>/ig;
    $comment =~ s/<BR>/\n> /ig;
    $comment =~ s/\n//;
    &html_form($FORM{'no'},$title,$comment,$FORM{'tn'},$lx);
    if (crypt($COOKIE{'pwd'},"FlasH_BBS_Pro") eq $file_pwd) {
        print<<"_EOF_";
<HR SIZE=1>
<CENTER>
<FORM ACTION="./flashbbs.cgi" METHOD="post">
<INPUT TYPE=hidden NAME=id VALUE=$ID>
<INPUT TYPE=hidden NAME=md VALUE="del">
<INPUT TYPE=hidden NAME=tn VALUE="$FORM{'tn'}">
<INPUT TYPE=hidden NAME=no VALUE="$FORM{'no'}">
<INPUT TYPE=hidden NAME=pwd VALUE="$COOKIE{'bbs_pwd'}">
<INPUT TYPE=submit VALUE="この記事の内容を削除する">
</FORM>
（完全に削除されない場合があります。）
</CENTER>
_EOF_
    }
}

# [ セット表示 ]
#

sub set {
    &html_header("セット表\示");
    print<<"_EOF_";
<A NAME="list">
<HR SIZE=1>
<CENTER>セット表\示</CENTER><P>
<PRE>
_EOF_
    @kiji_datas = &divide_log(&search_no2data($FORM{'tn'},@logs));
    foreach (@kiji_datas) {
        local($no,$res,$lx,$tn,$title,$name,$email,$date,$act) = &divide_data($_);
        $no = int($no);
        $reply[$res] .= "$no-";
        if ($res eq 'root') {
            print "<IMG SRC=\"$gif_allnews\" WIDTH=$gif_width HEIGHT=$gif_height BORDER=0>";
        } else {
            local($space_width) = $gif_width+$tree_width*$lx;
            print "<IMG SRC=\"$gif_space\" WIDTH=$space_width HEIGHT=$gif_height>";
        }
        print "<A HREF=\"#$no\"><IMG SRC=\"$gif_news\" WIDTH=$gif_width HEIGHT=$gif_height BORDER=0>$title</A> : $name<FONT COLOR=\"$em_color\">($date)</FONT>\n";
    }
    foreach $data (@kiji_datas) {
        local($no,$res,$lx,$tn,$title,$name,$email,$date,$act,$pwd,$rhost,$ipad,$comment) = &divide_data($data);
        $no = int($no);
        print<<"_EOF_";
</PRE>
<A NAME="$no">
<CENTER><P>
<HR SIZE=1><P>
<A HREF="flashbbs.cgi?id=$ID&md=viw&no=$no&tn=$FORM{'tn'}">返事を書く</A>|<A HREF="#list">リスト</A>
<TABLE WIDTH=95% BORDER=1><TR><TD WIDTH=10% ALIGN="center">
<B>$no</B>
</TD><TD WIDTH=10%>
_EOF_
        if ($res eq 'root') {
            print" <TT>Root</TT>\n";
        } else {
            $res = int($res);
            print"<A HREF=\"#$res\">▲</A><FONT COLOR=\"$em_color\"><TT>[$res]</TT></FONT>\n";
        }
        print"</TD><TD>\n";
        if (!$reply[$no]) {
            print"なし\n";
        } else {
            chop($reply[$no]);
            local(@replys) = split(/-/,$reply[$no]);
            foreach (@replys) {
                print"<A HREF=\"#$_\">▼</A><FONT COLOR=\"$em_color\"><TT>[$_]</TT></FONT>\n";
            }
        }
        print"</TD></TR><TR><TD COLSPAN=3>\n";
        &kiji_view($data);
        print<<"_EOF_";
</TD></TR></TABLE>
</CENTER>
_EOF_
    }
}

# [ 最新記事一括機能 ]
#

sub number {
    &html_header("最新記事");
    print<<"_EOF_";
<HR>
<CENTER>
最近の記事 <FONT COLOR="$em_color"><B>$new_kiji</B></FONT>件を表\示しています。
</CENTER>
_EOF_
    $count = (&read_file($countfile))[0];
    foreach (@logs) {
        @datas = &divide_log($_);
        foreach $data (@datas) {
            local($no,$res,$lx,$tn,$title,$name,$email,$date,$act) = &divide_data($data);
            if ($no > $count - $new_kiji) { push(@nums,$data); }
        }
    }
    @nums = reverse(sort(@nums));
    foreach $data (@nums) {
        local($no,$res,$lx,$tn,$title,$name,$email,$date,$act,$pwd,$rhost,$ipad,$comment) = &divide_data($data);
        print<<"_EOF_";
<CENTER><P>
<HR SIZE=1><P>
<A HREF="flashbbs.cgi?id=$ID&md=viw&no=$no&tn=$tn">返事を書く</A>|<A HREF="flashbbs.cgi?id=$ID&md=set&tn=$tn">セットで表\示</A>
<TABLE WIDTH=95% BORDER=1><TR><TD WIDTH=10% ALIGN="center">
_EOF_
        &kiji_view($data);
        print<<"_EOF_";
</TD></TR></TABLE>
</CENTER>
_EOF_
    }
}

# [ 投稿フォームを表示 ]
#

sub html_form {
    local($no,$title,$comment,$tn,$lx) = (@_);
    if ($no eq '') { $no = 'root'; }
    $nam_wid = 35;
    $com_wid = 42;
    $agent = $ENV{'HTTP_USER_AGENT'};
    if ($agent =~ /MSIE 3/i) {
        $nam_wid = 65;
        $com_wid = 85;
    } elsif ($agent =~ /MSIE 4/i) {
        $nam_wid = 65;
        $com_wid = 55;
    } elsif (($agent =~ /[ja]/i) && ($agent =~ /3\./)) {
        $nam_wid = 46;
        $com_wid = 55;
    }
    print<<"_EOF_";
<CENTER>
<FORM ACTION="./flashbbs.cgi" METHOD="post">
<INPUT TYPE=hidden NAME=id VALUE=$ID>
<INPUT TYPE=hidden NAME=md VALUE=reg>
<INPUT TYPE=hidden NAME=no VALUE=$no>
<INPUT TYPE=hidden NAME=tn VALUE=$tn>
<INPUT TYPE=hidden NAME=lx VALUE=$lx>
<INPUT TYPE=hidden NAME=pwd VALUE=$COOKIE{'pwd'}>
<TABLE BORDER=1 BGCOLOR="$form_bgcolor">
<TR><TD>
<TABLE><TR><TD><TT>
<B>タイトル</B>
</TT></TD><TD>
<INPUT TYPE=text NAME=title SIZE=$nam_wid MAXLENGTH=80 VALUE="$title">
</TD></TR><TR><TD><TT>
<B>ハンドル</B>
</TT></TD><TD>
<INPUT TYPE=text NAME=name SIZE=$nam_wid MAXLENGTH=42 VALUE="$COOKIE{'name'}">
</TD></TR><TR><TD><TT>
<B>Ｅメール</B>
</TT></TD><TD>
<INPUT TYPE=text NAME=email SIZE=$nam_wid MAXLENGTH=120 VALUE="$COOKIE{'email'}">
</TD></TR></TABLE>
</TD></TR><TR><TD>
<TEXTAREA NAME=comment ROWS=8 COLS=$com_wid WRAP="soft">$comment</TEXTAREA>
</TD></TR><TR><TD>
<INPUT TYPE=submit VALUE="この記事を送信する">
<INPUT TYPE=reset VALUE="取り消し">
</TD></TR></TABLE>
</FORM>
</CENTER>
_EOF_
}

# [ 記事内容を表示 ]
#

sub kiji_view {
    local($data) = $_[0];
    local($no,$res,$lx,$tn,$title,$name,$email,$date,$act,$tm_pwd,$rhost,$ipad,$comment) = &divide_data($data);
    $comment ="<!--$rhost($ipad)-->$comment";
    &jcode'convert(*comment,'euc');
    $comment =~ s/>(&gt;[^<]*)/><FONT COLOR=\"$res_color\">$1<\/FONT>/g;
    $comment =~ s/(http:\/\/[\w\.\~\-\/\?\&\+\=\:\@\%]+)/<A HREF=\"$1\">$1<\/A>/ig;
    $comment =~ s/(ftp:\/\/[\w\.\~\-\/]+)/<A HREF=\"$1\">$1<\/A>/ig;
    $comment =~ s/([\w\.\-]+)\@([\w\.\-]+)/<A HREF=\"mailto\:$1\@$2\">$1\@$2<\/A>/ig;
    &jcode'convert(*comment,$mojicode);
    if ($email) { $name = "<A HREF=\"mailto:$email\">$name</A>"; }
    print<<"_EOF_";
<CENTER><TABLE WIDTH=90% CELLPADDING=5>
<TR><TD ALIGN="center" BGCOLOR="$kiji_title_bgcolor">
<FONT SIZE=+1 COLOR="$kiji_title_color"><B>$title</B></FONT>
</TD></TR><TR><TD>
<DIV ALIGN="right">$name<FONT COLOR="$em_color">($date)</FONT></DIV>
<P>
$comment
<P>
</TABLE></CENTER>
_EOF_
}

# [ 記事登録処理 ]
#

sub regist {
    local($title,$name,$email,$comment,$lx,$tn,$pwd,$ref_url) = ($FORM{'title'},$FORM{'name'},$FORM{'email'},$FORM{'comment'},$FORM{'lx'},$FORM{'tn'},$FORM{'pwd'},$ENV{'HTTP_REFERER'});
    $title =~ s/\r\n//g;
    $title =~ s/\r|\n//g;
    $name  =~ s/\r\n//g;
    $name  =~ s/\r|\n//g;
    $email =~ s/\r\n//g;
    $email =~ s/\r|\n//g;
    $comment =~ s/\r\n/<BR>/g;
    $comment =~ s/\r|\n/<BR>/g;
    $lx++;
    $pwd =~ s/\r\n//g;
    $pwd =~ s/\r|\n//g;
    $ref_url =~ s/\?(.|\n)*//g;
    s/\%7E/\~/g;
    if($base_url && ($ref_url !~ $base_url)){
        &error(1,"不当なアクセスです。$ref_url<BR>\n");
    }
    if (length($title) > 80) {
        &error(1,"タイトルの記入漏れ、又は文字数制限を過えています。");
    } elsif (!$title) { $title = "無題"; }
    if ((!$name) || (length($name) > 42)) {
        &error(1,"名前の記入漏れ、又は文字数制限を過えています。");
    }
    if ((($email !~ /(.*)\@(.*)\.(.*)/) && ($email)) || (length($email) > 120)) {
        &error(1,"メールアドレスの間違い、又は文字数制限を過えています。");
    }
    if ((!$comment) || (length($comment) > $max_msg)) {
        &error(1,"メッセージの記入漏れ、又は文字数制限を越えています。");
    }
    if ((!$pwd) || (length($pwd) > 8)) { $pwd = &make_pwd; }
    $file_pwd = crypt($pwd,"FlasH_BBS_Pro");
    &get_date;

    $count = (&read_file($countfile))[0];
    if (++$count > 9999) {
        &error(1,"カウンターエラーです。管理者はエディタで最適化を行って下さい。");
    }
    &write_file($countfile,$count);
    $count = substr("0000",length($count)).$count;

    $rhost = &change_code($ENV{'REMOTE_HOST'});
    $ipad  = &change_code($ENV{'REMOTE_ADDR'});
    if ($FORM{'no'} eq 'root') {
        $kiji_data = "$count<>root<>0<>$count<>$title<>$name<>$email<>$date<>0<>$file_pwd<>$rhost<>$ipad<>$comment\n";
        unshift(@logs,$kiji_data);
    } else {
        foreach $tree (@logs) {
            if ($tn == (split(/<>/,$tree))[0]) {
                @datas = &divide_log($tree);
                $flag1 = 0; $flag2 = 0;
                $kiji_data = "$count<>$FORM{'no'}<>$lx<>$tn<>$title<>$name<>$email<>$date<>0<>$file_pwd<>$rhost<>$ipad<>$comment";
                foreach $data (@datas) {
                    if (($flag2 == 1) && ($temp_lx >= (split(/<>/,$data))[2])){
                        $tree_data = "$tree_data<#>$kiji_data";
                        $flag2 = 2;
                    }
                    if ($flag1) { $tree_data = "$tree_data<#>$data"; }
                    else { $tree_data = $data; $flag1 = 1; }
                    if (($FORM{'no'} == (split(/<>/,$data))[0]) && (!$flag2)) {
                        $flag2 = 1; $temp_lx = (split(/<>/,$data))[2];
                    }
                }
                if ($flag2 == 1){ $tree_data = "$tree_data<#>$kiji_data"; }
                unshift (@new,"$tree_data\n");
            }
            else { push (@new,$tree); }
        }
        @logs = @new;
    }
    if ($max_size <1500) { $max_size = 1500; }
    $size = (stat($logfile))[7];
    while ($size > $max_size) { $size -= length(pop(@logs)); }
    &write_file($logfile,@logs);
    $COOKIE{'name'} = $name;
    $COOKIE{'email'} = $email;
    $COOKIE{'pwd'} = $pwd;
    &set_cookie;
    &html_header("投稿受理報告");
    print<<"_EOF_";
<HR SIZE=1>
<P>
<CENTER>
<B>以下の内容で記事は受理されました。</B>
<P>
<FORM ACTION="flashbbs.cgi">
<INPUT TYPE=hidden NAME=id VALUE=$ID>
<INPUT TYPE="submit" VALUE="ここをクリックして下さい">
</FORM>
</CENTER>
<P>
<HR SIZE=1>
_EOF_
    &kiji_view($kiji_data);
    &html_footer;
    exit;
}

# [ 投稿者削除処理 ]
#

sub delete {
    @kiji_datas = &divide_log(&search_no2data($FORM{'tn'},@logs));
    $kiji_data = &search_no2data($FORM{'no'},@kiji_datas);
    local($no,$res,$lx,$tn,$title,$name,$email,$date,$act,$file_pwd,$rhost,$ipad,$comment) = &divide_data($kiji_data);
    if (crypt($COOKIE{'pwd'},"FlasH_BBS_Pro") ne $file_pwd) {
        &error(1,"指定した記事の削除はできません。");
    }
    &get_date;
    $kazu = @kiji_datas;
    if ($kazu == 1) {
        foreach $data (@logs) {
            if ($FORM{'no'} != (split(/<>/,$data))[0]) { push(@new,$data); }
        }
    } else {
        $kiji_data = "$no<>$res<>$lx<>$tn<><I>[投稿者削除]</I><>$name<><>$date<>8<>Null<>$rhost<>$ipad<>投稿者によって削除されました。($date)";
        $flag = 0;
        foreach $data (@kiji_datas) {
            if ($flag) { $tree_data .= "<#>"; } else { $flag = 1; }
            if ($FORM{'no'} == (split(/<>/,$data))[0]) { $tree_data .= $kiji_data; }
            else { $tree_data .= $data; }
        }
        $tree_data =~ s/\n//;
        foreach $data (@logs) {
            if ($FORM{'tn'} != (split(/<>/,$data))[0]) { push(@new,$data); }
            else { push(@new,"$tree_data\n"); }
        }
    }
    &write_file($logfile,@new);
    &html_header("投稿者削除");
    print<<"_EOF_";
<HR SIZE=1>
<P>
<CENTER>
<B>記事の内容を削除しました。</B>
<P>
ツリー掲示板の性質上、完全には削除されない場合があります（レス等がある場合）<BR>
完全に削除することを望む場合は管理者にお伝え下さい。
<P>
<FORM ACTION="flashbbs.cgi">
<INPUT TYPE=hidden NAME=id VALUE=$ID>
<INPUT TYPE="submit" VALUE="ここをクリックして下さい">
</FORM>
</CENTER>
<P>
_EOF_
}

# [ データ処理関連汎用サブ ]
#

sub divide_log {
    local($data) = $_[0];
    chop($data);
    return split(/<#>/,$data);
}
sub divide_data {
    return split(/<>/,$_[0]);
}
sub search_no2data {
    local($no,@datas) = @_;
    local($data);
    foreach $data (@datas) {
        if ($no == (split(/<>/,$data))[0]) { return $data; }
    }
    return 0;
}

# [ フォームからデータ取得 ]
#

sub read_form {
    local($pair,$buffer);
    if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; }
    local(@pairs) = split(/&/,$buffer);
    foreach $pair (@pairs) {
        local($name,$value) = split(/=/,$pair);
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
        $FORM{$name} = &change_code($value);
    }
}

# [ クッキー処理 ]
#

sub check_cookie {
    local($text);
    foreach $text ('font','sort','tree','form','new_mail','res_mail') {
        if (($FORM{$text} ne '') && ($COOKIE{$text} ne $FORM{$text})) { $COOKIE{$text} = $FORM{$text}; }
    }
}
sub get_cookie {
    local($pair,%DUMMY);
    local($cookies) = $ENV{'HTTP_COOKIE'};
    local(@pairs) = split(/;/,$cookies);
    foreach $pair (@pairs) {
        local($name,$value) = split(/=/,$pair);
        $name =~ s/ //g;
        $DUMMY{$name} = $value;
    }
    @pairs = split(/,/,$DUMMY{$cookie_name});
    foreach $pair (@pairs) {
        local($name,$value) = split(/:/,$pair);
        $COOKIE{$name} = &change_code($value);
    }
}
sub set_cookie {
    local($cook) = "name\:$COOKIE{'name'}\,email\:$COOKIE{'email'}\,pwd\:$COOKIE{'pwd'}\,font\:$COOKIE{'font'}\,sort\:$COOKIE{'sort'}\,tree\:$COOKIE{'tree'}\,form\:$COOKIE{'form'}\,new_mail\:$COOKIE{'new_mail'}\,res_mail\:$COOKIE{'res_mail'}";
    $ENV{'TZ'} = "GMT"; # 国際標準時の取得

    local($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time + 30*24*60*60);
    if ($year < 99) { $year += 100; }
    $year += 1900;
    if ($sec  < 10)  { $sec  = "0$sec";  }
    if ($min  < 10)  { $min  = "0$min";  }
    if ($hour < 10)  { $hour = "0$hour"; }
    if ($mday < 10)  { $mday = "0$mday"; }
    $mon = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$mon];
    $youbi = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')[$wday];
    $date_gmt = "$youbi, $mday\-$mon\-$year $hour:$min:$sec GMT";
    print "Set-Cookie: $cookie_name=$cook; expires=$date_gmt\n";
}

# [ 文字コード関連 ]
#

sub check_code {
    if (!(-r $jcode)) { &error(1,"jcode.pl がありません"); }
    require $jcode;
    local($text) = ord(substr("中澤重人＝じゃわ(^-^;;",0,1));
    if ($text == 0xc3) { $mojicode = "euc"; $charset_code = "x-euc-jp"; }
    elsif ($text == 0x92) { $mojicode = "sjis";$charset_code = "x-sjis"; }
    else { &error(1,"サポートしてない文字コードです"); }
}
sub change_code {
    local($text)=$_[0];
    &jcode'convert(*text,$mojicode);
    if ($mojicode eq 'sjis') { &jcode'h2z_sjis(*text); }
    if ($mojicode eq 'euc')  { &jcode'h2z_euc(*text); }
    $text =~ s/</&lt;/g;
    $text =~ s/>/&gt;/g;
    return $text;
}

# [ 日付取得 ]
#

sub get_date {
    $ENV{'TZ'} = "JST-9"; # TimeZone (日本時間 = 国際標準時(JST) - 9時間)
    local($sec,$min,$hour,$day,$mon,$year) = localtime();
    if ($year < 99) { $year += 100; }
    $year += 1900;
    $year = substr($year,length($year)-2,2);
    $mon++;
    if ($date_type) {
        if ($sec < 10)  { $sec = "0$sec";   } # 秒の修正
        if ($min < 10)  { $min = "0$min";   } # 分  〃
        if ($hour < 10) { $hour = "0$hour"; } # 時  〃
        if ($date_type > 1) {
            if ($mon < 10)  { $mon = "0$mon";   } # 月  〃
            if ($day < 10)  { $day = "0$day";   } # 日  〃
        }
    }
    $date =~ s/year/$year/ig;
    $date =~ s/mon/$mon/ig;
    $date =~ s/day/$day/ig;
    $date =~ s/hour/$hour/ig;
    $date =~ s/min/$min/ig;
    $date =~ s/sec/$sec/ig;
}

# [ 記録ファイルの処理 ]
#

sub read_file {
    local($logfile) = $_[0];
    &lock_file($lock1);&lock_file($lock2);
    if ($lock_error) { &error(1,"ロックファイルを検出しました。時間をおいてご利用下さい。"); }
    if (!open(IN,$logfile)) { &unlock_file; &error(1,"記録ファイルの読み込み不可"); }
    local(@files) = <IN>;
    close(IN);
    &unlock_file($lock2);&unlock_file($lock1);
    return @files;
}
sub write_file {
    local($logfile,@lines) = @_;
    &lock_file($lock1);&lock_file($lock2);
    if ($lock_error) { &error(1,"ロックファイルを検出しました。時間をおいてご利用下さい。"); }
        if (!open(OUT,">$logfile")) { &unlock_file; &error(1,"記録ファイルの書き込み不可"); }
    print OUT @lines;
    close(OUT);
    &unlock_file($lock2);&unlock_file($lock1);
    return @lines;
}

# [ ロック機構 ]
#

sub lock_file {
    local($lockfile) = $_[0];
    if (!$lock_flag) { return 1; }
    local($retry) = 5;
    while (-f $lockfile) {
        if ($retry-- <= 0) {
            local($mtime) = (stat($lockfile))[9];
            if ($mtime < time()-60*15) { &unlock_file($lockfile); }
            $lock_error = 1;
            return 1;
        }
        sleep 1;
    }
    open (LOCK,">$lockfile");
    close(LOCK);
    return 1;
}
sub unlock_file {
    local($lockfile) = $_[0];
    unlink($lockfile);
}

# [ パスワード処理 ]

sub make_pwd {
    local($pwd) = '';
    srand;
    for ($i=0;$i<8;$i++) { $pwd .= substr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",int(rand(62)),1); }
    return $pwd;
}

# [ エラー処理 ]
#

sub error {
    ($err,$err_msg) = @_;
    if ($err) { print "Content-type: text/html\n\n<HTML><BODY>"; }
    print<<"_EOF_";
<P><TABLE BGCOLOR="white" CELLPADDING=5 WIDTH=100%><TD ALIGN=center>
<FONT COLOR="red"><B>エラー:$err_msg</B></FONT>
</TD></TABLE>
</BODY></HTML>
_EOF_
    exit;
}
