#!/usr/bin/perl

#　Smart Board ver 1.12a - Force 264 v3.22A Based -
#
# ■ このスクリプトについて
#
#　　このスクリプトは Force 264 [ http://www3.digitalworkz.com/~carl/ ] で
#　　配布されていた、Carlさん作 Force 264 BBS v3.22A を改造したものです。
#　　レス機能、固定ＩＤ機能、その他の変更･追加をしています。
#　　悪戯対策の部分はオリジナルとほぼ同様です。
#
# ■ Rewrite by Hermitz [ http://popup2.tok2.com/home/newbie/index.shtml ] => Last Fixed：2002/1/27
#
#　　Perl初心者が改造したようなものなのでバグを発見されたらご報告のほど宜しくお願いします。
#
# <利用規定>
#　1.このスクリプトの改造は可です。ただし、改造の有無に関わらず再配布をすることは禁止とします。
#　2.改造の有無に関わらず、作成元の Force 264 [ http://www3.digitalworkz.com/~carl/ ] と
#　　改造元の For Newbies [ http://popup2.tok2.com/home/newbie/index.shtml ] を明記して下さい。
#　3.このスクリプトを有償で設置したりする場合（レンタル等）は連絡ください。
#
# ■ スクリプトの詳しい設置方法は、同梱されている readme.txt を参照して下さい。
#
# ※この掲示板のことはCarlさんに連絡済です。
# 
############################################################################################

#----------------#
#    初期設定    #
#----------------#

# 掲示板の設置アドレス
$reload = 'http://contest2004.thinkquest.jp/tqj2004/70105/cgi-bin/BBS.cgi';

# ホームページアドレス
$home = 'http://contest2004.thinkquest.jp/tqj2004/70105/';

#-------- ファイル設定 ------------#

# 日本語コード変換ライブラリ
require 'JCode.pl';

# パスワードファイル
$pass = './pwdCode.txt'; #必ず名称変更すること

# 掲示板のログファイル
$file = './LogFile.txt';
$max = 50; # 最大記録件数（親記事：これを超えると古い順に削除されます）
$max_res = 0; # 記事に対する最大返信数（0で無制限) 

# カウンターファイル
$counter = './CounterFile.dat';

# フェイザー対策用の画像投稿コード生成用CGIファイルの指定（by ひみこ氏）
$himicode = './RandomNumber.cgi';

# 発行済みチェックコードを保存するファイル
$himicode_log = './hiddenCode.txt'; #必ず名称変更すること

# 投稿コード記録ファイル
$code_log = './CodeData.txt';
$maxline = '100';   # 最大保存件数（設定数以上は古いものから順に削除）

# 指定ホスト排除用ファイル
$hostlist = 'HostDelete.txt';

# アクセスログ記録ファイル
$access_log = './information.txt';  # アクセスログを使う場合の記録ファイルの設定 #必ず名称変更すること
$rescue = '200';            # アクセスログ最大記録件数（設定数以上は古いものから順に削除）

# ＩＤを記録するファイル
$idlist = './IDCodeData.txt';
$max_id = 0; # ＩＤ最大記録件数（0で無制限。制限数を超えた場合はＩＤ登録ができなくなります。）

#----------------#
#    動作設定    #
#----------------#

# body タグ（HTMLと同様）
$body = '<BODY bgcolor="#003399" text="#FFFFFF" link="orange" vlink="white"><hr>';

# スタイルシート（HTMLと同様）
$style = '
<STYLE type="text/css">
<!--
BODY,TD,TH { font-size: 10pt; line-height: 12pt; }
A:hover { COLOR: lightgreen; TEXT-DECORATION: underline }
-->
</STYLE>
';

# １ページに表示するスレッド数
$max_sr = 10;

# 書き込み容量制限　※ 0 にすると無制限（全角は約２バイトです）（by カール）
$max_s = 40;         #タイトル文字数
$max_n = 24;         #名前文字数
$max_v = 6500;       #投稿内容文字数
$max_line = 75;      #投稿内容行数（上の文字数との兼ね合いを考えて）
$max_mail = 70;      #メールアドレス文字数
$max_home = 70;      #サイトアドレス文字数

#----------------------------------------------
# カウンターを表示するかどうか（表示しない: 0 表示する: 1）
$clog = 1;
$c_color = '<font color="lightgreen">'; #テキストカウンターの色

# タイトルの文字色
$t_color = 'white';

# 掲示板のタイトル
$title = '右脳数学ミュージアム掲示板';

# 記事の背景色
$tbgcolor = '';

# 記事の枠線の色（IEのみ有効）
$tbrcolor = '#FFFFFF';

# 題名の前に表示するポイント（表示したくない場合は $tpoint = ''; として下さい。）
$tpoint = '';

# 題名の前に表示するポイントの色
$tpcolor = '#ff9326';

# 記事の題名の文字色
$tscolor = 'skyblue';

# 投稿者の名前の色
$n_color = 'lightsteelblue';

# ホームページの表示方法（ ' を使用したい場合は \' として下さい。例：That's なら That\'s ）
$hpoint = 'HOME';

# 文字色の選択
@colors = ('#FFFFFF','pink','yellow','yellowgreen','lime','aqua','magenta','tomato','red');

# > または ＞ で始まる行の色
$recolor = '<FONT color="lightgreen">';

#-----------------------------------------------

# タグの使用（使える：1 使えない：0）
$tag = 0;

# アクセスログ取得（する：1 しない：0）
$alog = 1;

# プロクシ経由でのアクセス（閲覧）＆書き込み（ＩＤ登録含む）の許可（by カール＆dimdim氏＆ひみこ氏）
# 許可する : 0　書き込みのみ拒否する（閲覧は可）: 1　閲覧、書き込み共に拒否: 2
$proxy = 0;

# プロクシ制限する場合のレベル（弱 : 1　強 : 2）
# ２にするとプロクシ変数をまったく吐かないＪＰ串以外はほとんど拒否します。
$plevel = 1;

# 上記プロクシ制限をした場合に善意のアクセス者（会社のFireWall等）を指定して許可する設定
# ホスト名を|で区切って複数指定可能。IPアドレスの場合は先頭の２つが適当？
# 設定例：$kyoka = "biglobe.be.jp|3web.ne.jp|202.124.|abc.com";
$kyoka = "";

#----- 管理者設定 --------------------#

# 騙り（かたり）防止のため投稿者の認識ＩＤを投稿日の後ろに表示する（by /../氏　mm氏　カール）
# （ＩＤは、削除パスワードとハンドル名の組み合わせで暗号化（登録したＩＤの場合はそのまま）され固定されます。）
# 認識ＩＤを表示しない : 0　表示する: 1
$DispID = 1;

# 固定ＩＤ機能の設定（使用する：1　しない：0）※DispID = 0; の場合は $use_id = 0; にして下さい
$use_id = 1;

# 登録拒否するID設定（指定した文字を含むときも全てキック。大文字・小文字の違いは無視）
# ホスト名を|で区切って複数指定可能
# 設定例：$denyID = 'master|admin|root';
$denyID = 'admin|webmaster|master|root';

# 管理者名の設定
$master = '管理人';

# 管理者名とパスワードが同一の場合に表示するＩＤ（半角の : は使えません。ＩＤの表示等がおかしくなります。）
$master_id = '<font color="lime">管理人</font>';

# IPアドレス・リモートホスト・HTTP_USER_AGENTの表示
# 表示しない：0　表示する：1
$DispHost = 0;

# レス（返信）をした場合にスレッド（記事）を上げる
# 上げない：0　上げる：1
$resup = 1;

#--------------------------------
# 管理者の名前や使われたくない名前を使用拒否する（偽名拒否設定 by TTS氏）
# 偽名拒否設定しない : 0　する: 1
$gimei = 1;

# 偽名を拒否する範囲（下記設定で「拒否する名前を含む時」にした場合、全角のーが入った名称は使用不可）
#（拒否する名前と一致する時のみ：0 拒否する名前を含む時：1）
$g_length = 0;

# 偽名拒否設定する場合の拒否ハンドル、名称の設定。（半角開けて複数指定可）
# 管理者は削除パスワード欄に管理パスワードを入れればどんな名前でも書けます。（by カール）
$admin = '主催者 管理者 管理人';  # $g_length = 1; の場合、全角のーが入った名称は使用不可（エラーになる）

# (上記偽名を使った場合と)排除指定したホストのジャンプするＵＲＬ　デフォは文部省（笑）＜TTS氏
$jumpurl = "http://www.monbu.go.jp/";

#--------------------------------
# GabriDuke等のランダム連続投稿ツール対策チェックコード生成用（by 工場長）
# $num1,$num2,$key は himicode.cgi 内の設定と同一にして下さい。
$num1 = 31415; # （1〜99999までの任意の５桁以内の数字で必ず変更すること）
$num2 = 68; # （10〜99までの任意の２桁以内の数字で必ず変更すること）

# チェックコードをさらにキーで暗号化（チェックコード法則性の推測予防）（by カール）
$key = 'AtomicBomb'; # （任意の文字列を暗号キーにする　※必ず変更すること）
#--------------------------------
# ダブルポスト（２重投稿）チェック（ログが大きいと負荷が掛かるかもしれません）
# する：1　しない:0
$d_check = 1;

# チェックレベル（簡易：1 完全：2）
# ※簡易はサーバーへの負荷を軽減します。完全はログファイルが大きい場合サーバーへかなりの負荷が掛かります。
$dplev = 1;

# チェックする件数（何件前まで：連続投稿チェックと兼用）
$dc = 5;

# チェックするバイト数（全角は２バイト）
$checklength = 100;

# 連続投稿チェック（ＩＤ登録時と兼用。ログが大きいと負荷が掛かるかもしれません）
# する：1　しない：0
$p_check = 1;

# チェックする範囲（同一ホストのみ：0　全て：1）
$ctimer = 0;

# 連続投稿を制限する時間（分）※できるだけ長めに
$rtimer = 1;

# flock の使用（する：1 しない：0）※ログ、ＩＤ、カウンターファイルに有効です。
# どうしてもエラーが出る場合には $use_flock = 0; にしてみて下さい。
$use_flock = 1;

# 時刻の取得＆時差が生じる場合の修正
# 海外時間に＋９時間する場合　= localtime(time + 9*60*60);
($sec,$min,$hour,$mday,$mon,$year,$wday,$d,$d) = localtime(time);

#################################### 設定する項目はここまで #####################################

$timer = $rtimer * 100;
$youbi = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")[$wday];
$date_now = sprintf( " %02d/%02d $youbi %02d:%02d:%02d", $mon + 1, $mday, $hour, $min, $sec );
$date_num = sprintf("%02d%02d%02d%02d%02d",$mon +1,$mday,$hour,$min,$sec);
@key = split(//, $key);

$addr = $ENV{'REMOTE_ADDR'};
$host = $ENV{'REMOTE_HOST'};

if (($host eq $addr) || ($host eq '')) { 
  $host = gethostbyaddr(pack('C4',split(/\./,$addr)),2) || $addr;
}
if ($kyoka eq "") {
  &hostcheck;
} elsif ($host !~ /$kyoka/) {
  &hostcheck;
}

if ($alog == 1 || $proxy != 0) {
  $via    = $ENV{'HTTP_VIA'};
  $xfor   = $ENV{'HTTP_X_FORWARDED_FOR'};
  $for    = $ENV{'HTTP_FORWARDED'};
  $agent  = $ENV{'HTTP_USER_AGENT'};
  $trueip = &getip;
  $pcheck_flag = 1;
}

# Proxy経由の閲覧禁止の場合はProxyチェックへ。ただし書き込みのみ禁止の場合はここはスルー
if ( ($kyoka eq "") && ($proxy == 2) ) {
  &proxy;
} elsif ( ($host !~ /$kyoka/) && ($proxy == 2) ) {
  &proxy;
}

#form から送られてきたデータの変換

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

  if ($value =~ /\r\n/) { $value =~ s/\r\n/\r/g; }
  if ($value =~ /\n/)   { $value =~ s/\n/\r/g;   }
  # 改行連打のいたずらを回避（３行以上何も書かずに改行のみの部分は改行無視）（by カール）
  # スペース＋改行の連打を回避（上記を回避するためにスペースをいれて改行する悪戯の場合）
  if ($value =~ / \r \r/)     { $value =~ s/ \r \r//g;     }
  if ($value =~ /\　\r\　\r/) { $value =~ s/\　\r\　\r//g; }
  if ($value =~ / \r/)        { $value =~ s/ \r/\r/g;      }
  if ($value =~ /\　\r/)      { $value =~ s/\　\r/\r/g;    }
  if ($value =~ /\r\r\r\r/)   { $value =~ s/\r\r\r\r//g;   }

$value =~ s/&/&amp\;/g;

if ($tag != 1) {
  $value =~ s/</&lt;/g;
  $value =~ s/>/&gt;/g;
}
elsif ($name ne 'value') {
  $value =~ s/</&lt;/g;
  $value =~ s/>/&gt;/g;
}

if (($name eq 'value') || ($name eq 'subject') || ($name eq 'name')) { $value =~ s/\,/\0/g; }
else { $value =~ s/\,//g; }

$FORM{$name} = $value;

}

$FORM{'value'} =~ s/([a-zA-Z0-9_\,\:\;\^\/\-\~\=\<\>\!\"\#\$\%\&\'\@\`\+\*\?\.\(\)\[\]\{\}\|\\]{80})/\1<br>/g;

if ( !open(DB,"$hostlist") ) { &error('0'); }
@lines = <DB>;
close(DB);
$phas = shift(@lines);
chop($phas) if ($phas =~ /\n$/);
if ($phas =~ /phaser_on/) {
  $pict = 1;
}

if ( !open(DB,"$pass") ) { &error('0'); }
@lines = <DB>;
close(DB);
$password = shift(@lines);
chop($password) if ($password =~ /\n$/);
($header, $password) = split(/:/, $password);
if ($password =~ /^\$1\$/) {
  $salt = 3;
} else {
  $salt = 0;
}

#ID生成用のパス取り出し
$idps = pop(@lines);
chop($idps) if ($idps =~ /\n$/);
($0, $idps) = split(/:/, $idps);

if ($header ne 'crypt_password' || $password eq '') {
  $start = 1;
  &password;
}

if ($alog) {# アクセスログを取る場合の処理
    &acount;
  }

if ($FORM{'action'} eq 'pas' && $FORM{'papost'} eq 'pcode') { &password; }
elsif (($FORM{'action'} eq 'ad') && ($FORM{'admin'} eq 'change') && (crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password)) { &password; }
elsif($FORM{'action'} eq 'ad' && $FORM{'admin'} eq 'kick' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) { &kickhost; }
elsif ($FORM{'action'} eq 'ad' && $FORM{'admin'} eq 'cut' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) {
  &remove1;
  exit;
}elsif($FORM{'action'} eq 'osr' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) {
  &delete;
  &remove1;
  exit;
}elsif ($FORM{'action'} eq 'ad' && $FORM{'admin'} eq 'idps' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) {
  &idps;
}elsif ($FORM{'action'} eq 'idps' && $FORM{'admin'} eq 'idps2' && crypt($FORM{'password'}, substr($password,$salt,2)) eq $password) {
  &idps;
}elsif($FORM{'action'} eq 'kickout' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) {
  &kickhost;
  exit;
}elsif ($FORM{'action'} eq 'ad' && $FORM{'admin'} eq 'remid1' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) {
  &remid1;
}elsif ($FORM{'action'} eq 'remid2' && crypt($FORM{'pwd'}, substr($password,$salt,2)) eq $password) {
  &remid2;
  &remid1;
}
elsif ($FORM{'mode'} eq 'admin') { &admin; }
elsif ($FORM{'mode'} eq 'how') { &how; }
elsif (($FORM{'mode'} eq 'id') && ($use_id)) { &id; }
elsif (($FORM{'mode'} eq 'idpost') && ($use_id)) { &idpost; }
elsif (($FORM{'mode'} eq 'delid') && ($use_id)) { &del_id; }
elsif (($FORM{'action'} eq "post") && ($FORM{'value'} ne '') && ($FORM{'value'} ne ' ') && ($FORM{'value'} ne '　')) { &write_log; }
elsif ($FORM{'action'} eq "delete") { &delete; }

&html;

exit;


#################  ここから下はサブルーチン　#######################


#------------ HTML 表示 ---------------#

sub html {

if ($tpoint) {
  $point = "<font color=\"$tpcolor\">$tpoint</font>";
}

#----------返信の場合----------#

if (($FORM{'mode'} eq 'res') && ($FORM{'res'}) && ($FORM{'res_code'}) && ($FORM{'do'} eq '')) {

$match = 0;
$i = 0;
$through = 0;

open(LOG,"$file") || die "Can't Open LOG: $!\n";
while (<LOG>) {

 ($number, $spwd, $date, $name, $email, $value, $subject, $link, $host, $addr0, $via, $for, $trueip, $agent, $website, $checkcode, $r_total) = split(/\,/,);

$value =~ s/\0/\,/g;
$subject =~ s/\0/\,/g;
$name =~ s/\0/\,/g;

if (($DispID) && ($spwd ne '')) {
  if ($spwd =~ /\:/) {
    ($spwd, $d) = split(/:/,$spwd);
  }
  elsif ($spwd ne $master_id) {
    $spwd =~ s/^.*(.{11})$/ID:$1/;
  }
$spwd = "[$spwd]";
}
else {
  $spwd = "";
}

  $rec_flag = 0;
  if ($value =~ /^<font color="[#\w]*">/) { $rec_flag = 1; }
  $value =~ s/^(<font color="[#\w]*">)//;
  @t_value = split(/<br>/,$value);
  $value = "";
  for (@t_value) {
    if ($_ =~ /^&gt;|^＞|^>/) {
      $value .= "$recolor$_</font><br>";
    } else {
      $value .= "$_<br>";
    }
  }
  if ($rec_flag == 1) { $value = "$1$value"; }

if ($link == 1) {
$value =~ s/(https?|ftp|news):\/\/([\w|\!\#\$\%\&\'\(\)\=\-\^\`\\\|\@\~\[\{\]\}\;\+\:\*\,\.\?\/]+)/<a href=\"$1:\/\/$2\" target=\"_blank\">$1:\/\/$2<\/a>/g;
}

if ($email) {
  $name = "<a href=\"mailto:$email\">$name</a>";
}
else { $name = "<font color=\"$n_color\">$name</font>"; }

if (($website) && ($website ne "http://")) { $website = "<a href =\"$website\" target=\"_blank\">$hpoint</a>"; }
else { $website = ""; }

if (($FORM{'res'} eq $number) && ($FORM{'res_code'} eq $checkcode)) {

if (($r_total > $max_res) && ($max_res != 0)) { &errorz('返信数オーバー','返信が制限数を超えています。新しくスレッドを作成してください。'); }
$r_subject = "Re: $subject";

if ($DispHost) {
  $host0 = $host;
  if ($host0 =~ /[a-zA-Z]/) {
    $host0 =~ s/^[a-zA-Z0-9-]*\./\*\./;
  }
  else {
    $host0 =~ s/\.\d*$/\.\*/;
  }
$agent =~ s/</&lt;/g;
$agent =~ s/>/&gt;/g;
$ihu = "<p>[$host0 &gt\;&gt\; $agent]";
}

print <<"_HTML_";
Content-type: text/html

<html>
<head>
<title>$title</title>
$style
<script>
onload=enter;
function enter(){
document.ugbbs.name.value = ReadCookie("Name");
document.ugbbs.email.value = ReadCookie("Email");
document.ugbbs.website.value = ReadCookie("Website");
document.ugbbs.spwd.value = ReadCookie("Spwd");
document.ugbbs.color.value = ReadCookie("Color");}
function cook1(){WriteCookie("Name",document.ugbbs.name.value);}
function cook2(){WriteCookie("Email",document.ugbbs.email.value);}
function cook3(){WriteCookie("Website",document.ugbbs.website.value);}
function cook4(){WriteCookie("Spwd",document.ugbbs.spwd.value);}
function cook5(){WriteCookie("Color",document.ugbbs.color.value);}
function WriteCookie(keyword,data){
data=keyword+"="+escape(data)+";";
data+="expires=Fri,31-Dec-2050 23:59:59;";
document.cookie=data;}
function ReadCookie(keyword){
data=document.cookie+";";c=data.indexOf(keyword,0);
if(c!=-1){c+=(keyword.length+1);d=data.indexOf(";",c);
return(unescape(data.substring(c,d)));}return("");}
function DeleteCookie(keyword){data=keyword+"="+""+";";
data+="expires=Fri,31-Dec-2000 23:59:59;";
document.cookie=data;}
</script>
</head>
$body
[ <a href="#form">フォームへ</a> - <a href="$reload">戻る</a> ]
<br><br><center><H4>- 下記への返信です -</H4></center><br>
<CENTER>
<TABLE bordercolor="$tbrcolor" cellspacing="0" cellpadding="4" width="90%" bgcolor="$tbgcolor" border="1">
  <TBODY>
    <TR>
      <TD valign=baseline>$point<FONT color="$tscolor"><B>$subject</B></FONT>　投稿者：<B>$name</B> 投稿日：$date $website $spwd</TD>
    </TR>
    <TR>
      <TD>
      <BLOCKQUOTE><BR>
      $value $ihu
      <p>
_HTML_

$match = 1;
$temp_total = $r_total;
}

elsif (($r_total eq '') && ($i < $temp_total) && ($match == 1)) {

print <<"_HTML_";
      <HR width="98%" noshade size=1>
      <B><FONT color="$tscolor">$subject</FONT></B>　投稿者：<B>$name</B> 投稿日：$date $website $spwd<BR>
      <BLOCKQUOTE>
      $value $ihu
      </BLOCKQUOTE>
_HTML_

$i++;
}
elsif ($match == 1) {

   print "      </BLOCKQUOTE>\n";
   print "     </TD></TR>\n";
   print "   </TBODY>\n";
   print "</TABLE>\n";
   print "</center>\n";
   $through = 1; 
   last;
   }
}
close(LOG);
if ($through == 0) {
   print "      </BLOCKQUOTE>\n";
   print "     </TD></TR>\n";
   print "   </TBODY>\n";
   print "</TABLE>\n";
   print "</center>\n";
}
&form;
}

#------通常の表示-------#

else {

print <<"_HTML_";
Content-type: text/html

<html>
<head>
<title>$title</title>
<script>
onload=enter;
function enter(){
document.ugbbs.name.value = ReadCookie("Name");
document.ugbbs.email.value = ReadCookie("Email");
document.ugbbs.website.value = ReadCookie("Website");
document.ugbbs.spwd.value = ReadCookie("Spwd");
document.ugbbs.color.value = ReadCookie("Color");}
function cook1(){WriteCookie("Name",document.ugbbs.name.value);}
function cook2(){WriteCookie("Email",document.ugbbs.email.value);}
function cook3(){WriteCookie("Website",document.ugbbs.website.value);}
function cook4(){WriteCookie("Spwd",document.ugbbs.spwd.value);}
function cook5(){WriteCookie("Color",document.ugbbs.color.value);}
function WriteCookie(keyword,data){
data=keyword+"="+escape(data)+";";
data+="expires=Fri,31-Dec-2050 23:59:59;";
document.cookie=data;}
function ReadCookie(keyword){
data=document.cookie+";";c=data.indexOf(keyword,0);
if(c!=-1){c+=(keyword.length+1);d=data.indexOf(";",c);
return(unescape(data.substring(c,d)));}return("");}
function DeleteCookie(keyword){data=keyword+"="+""+";";
data+="expires=Fri,31-Dec-2000 23:59:59;";
document.cookie=data;}
</script>
$style
</head>
$body
_HTML_

&form;

$flag = 0;
$i = 0;
if ($FORM{'page'} eq '') { $sr = 0; }
else { $sr = $FORM{'page'}; }
$page_start = $sr + 1;
$page_end = $max_sr + $sr;
$s = 0;

print "<CENTER>\n";
print "<form method=\"POST\" action=\"$reload\">\n";
print "<input type=hidden name=\"action\" value=\"delete\">\n";

open(LOG,"$file") || die "Can't Open LOG: $!\n";
while (<LOG>) {

 ($number, $spwd, $date, $name, $email, $value, $subject, $link, $host, $addr, $via, $for, $trueip, $agent, $website, $checkcode, $r_total) = split(/\,/,);

if ($r_total ne '') { $s++; }
if ($s > $page_end) { last; }
if ($s < $page_start) { next; }

$value =~ s/\0/\,/g;
$subject =~ s/\0/\,/g;
$name =~ s/\0/\,/g;

if (($DispID) && ($spwd ne '')) {
  if ($spwd =~ /\:/) {
    ($spwd, $d) = split(/:/,$spwd);
  }
  elsif ($spwd ne $master_id) {
    $spwd =~ s/^.*(.{11})$/ID:$1/;
  }
$spwd = "[$spwd]";
}
else {
  $spwd = "";
}
  
  $rec_flag = 0;
  if ($value =~ /^<font color="[#\w]*">/) { $rec_flag = 1; }
  $value =~ s/^(<font color="[#\w]*">)//;
  @t_value = split(/<br>/,$value);
  $value = "";
  for (@t_value) {
    if ($_ =~ /^&gt;|^＞|^>/) {
      $value .= "$recolor$_</font><br>";
    } else {
      $value .= "$_<br>";
    }
  }
  if ($rec_flag == 1) { $value = "$1$value"; }

if ($link == 1) {
$value =~ s/(https?|ftp|news):\/\/([\w|\!\#\$\%\&\'\(\)\=\-\^\`\\\|\@\~\[\{\]\}\;\+\:\*\,\.\?\/]+)/<a href=\"$1:\/\/$2\" target=\"_blank\">$1:\/\/$2<\/a>/g;
}

if ($email) {
  $name = "<a href=\"mailto:$email\">$name</a>";
}
else { $name = "<font color=\"$n_color\">$name</font>"; }

if (($website) && ($website ne "http://")) { $website = "<a href =\"$website\" target=\"_blank\">$hpoint</a>"; }
else { $website = ""; }

if ($DispHost) {
  $host0 = $host;
  if ($host0 =~ /[a-zA-Z]/) {
    $host0 =~ s/^[a-zA-Z0-9-]*\./\*\./;
  }
  else {
    $host0 =~ s/\.\d*$/\.\*/;
  }
$agent =~ s/</&lt;/g;
$agent =~ s/>/&gt;/g;
$ihu = "<p>[$host0 &gt\;&gt\; $agent]";
}

if (($i < $temp_total) && ($flag == 1)) {

print <<"_HTML_";
      <HR width="98%" noshade size=1>
      <B><FONT color="$tscolor"><INPUT type="checkbox" name="del" value="$temp_sr:$number">$subject</FONT></B>　投稿者：<B>$name</B> 投稿日：$date $website $spwd<BR>
      <BLOCKQUOTE>
      $value $ihu
      </BLOCKQUOTE>
_HTML_

$i++;

  }
elsif ($flag == 1) {
   $i = 0;
   $flag = 0;
   print "      </BLOCKQUOTE>\n";
   print "    </TD></TR>\n";
   print "  </TBODY>\n";
   print "</TABLE><BR><BR>\n";
   }

if (($r_total ne "") && ($flag == 0)) { 

print <<"_HTML_";
<TABLE bordercolor="$tbrcolor" cellspacing="0" cellpadding="4" width="90%" bgcolor="$tbgcolor" border="1">
  <TBODY>
    <TR>
      <TD valign="baseline" width="89%"><INPUT type="checkbox" name="del" value="sr:$number">$point<FONT color="$tscolor"><B>$subject</B></FONT>　投稿者：<B>$name</B> 投稿日：$date $website $spwd</TD>　<TD align="center" width="11%"><a href="$reload?mode=res&res=$number&res_code=$checkcode">返信する</a></TD>
    </TR>
    <TR>
      <TD colspan="2">
      <BLOCKQUOTE><BR>
      $value $ihu
      <p>
_HTML_

$flag = 1;
$temp_sr = $number;
$temp_total = $r_total;
     }

 }
close(LOG);

print <<"_HTML_";
      </BLOCKQUOTE>
    </TD></TR>
  </TBODY>
</TABLE><BR><BR>
■投稿記事を削除：記事にチェックをいれてパスワード入力後ボタンを押して下さい
<TABLE bordercolor="$tbrcolor" cellspacing="0" cellpadding="4" bgcolor="$tbgcolor" border="1"><TR>
<TD>パスワード <INPUT type="password" name="spwd" size="8"> <INPUT type="submit" value="削除"></TD></FORM>
_HTML_

if ($page_end < $s) {

print <<"_HTML_";
<FORM method="POST" action="$reload">
<INPUT type="hidden" name="page" value="$page_end">
<TD>１ページ$max_sr件表\示  -&gt; <INPUT type="submit" value="NEXT"></TD></FORM>
_HTML_

}
else {
print "<TD>１ページ$max_sr件表\示 -&gt; 最後</TD>";
}

print <<"_HTML_";
<TH><A href="$reload">リロード</A></TH>
<TH><A href="$home" target="_top">ホーム</A></TH>
</TR></TABLE>
<BR>
<HR width="89%" noshade size=1>
<p align="right"><b>Rewrite by <a href="http://popup2.tok2.com/home/newbie/index.shtml" target="_blank">- For Newbies -</a> v1.12a</b><BR><b>Based on <a href="http://www3.digitalworkz.com/~carl/" target="_blank">- Force 264 -</a> v3.22A</b></p><hr>
_HTML_

}

print "</body>\n";
print "</html>";

exit;

}

#--------- 投稿フォーム表示 ------------------------------------#

sub form {

if ($clog) {# カウンター数値の処理
    &count;
  $c_number = "$c_color$c_number hits</font>";
  }
  
  $chcode = ($date_num + $num1) * $num2;
  # 投稿コードを任意のキーで暗号化
  $i = 0;
  $chcode =~ s/./sprintf("%02x",ord($&)^ord($key[$i++ % @key]))/ge;

if ($pict) { 
    $rport = $ENV{'REMOTE_PORT'};
    $himicode .= "?$ENV{'REMOTE_PORT'}";
  $KEYCODE = ""; #ひみこーどを使用する場合に表示するコメント
  }
unless (($FORM{'mode'} eq 'res') && ($FORM{'res'}) && ($FORM{'res_code'}) && ($FORM{'do'} eq '')) {
print <<"_HTML_";
$c_number &gt;&gt; $master [$master_id]<p>
<CENTER>
<H2><FONT color="$t_color">$title</FONT></H2>
<HR width="89%" noshade size="1">
_HTML_

  if (($DispID) && ($use_id)) {
      print "\| <A href=\"$home\">ホーム</A> \| <A href=\"$reload\">リロード</A> \| <A href=\"$reload?mode=how\">使い方</A> \| <A href=\"$reload?mode=id\">ＩＤ登録・削除</A> \| <A href=\"$reload?mode=admin\">管理モード</A> \|\n";
  } else {
      print "\| <A href=\"$home\">ホーム</A> \| <A href=\"$reload\">リロード</A> \| <A href=\"$reload?mode=how\">使い方</A> \| <A href=\"$reload?mode=admin\">管理モード</A> \|\n";
  }
  print "<HR width=\"89%\" noshade size=\"1\"></CENTER>\n";
}
else{
print "<br><br><HR width=\"89%\" noshade size=1>\n";
print "<center><H4><A name=\"form\">- 返信用フォーム -</a></H4></center>";
}
unless (($FORM{'mode'} eq 'res') && ($FORM{'res'}) && ($FORM{'res_code'}) && ($FORM{'do'} eq '')) { $r_subject = ''; }
print <<"_HTML_";
$KEYCODE
<DIV align="center">
<INPUT type="hidden" fake="hogehoge" name="facheck1"
 value="$addr">
<FORM action="$reload" method="POST" name="ugbbs">
<input type=hidden name="action" value="post">
<!--
<INPUT type="hidden" fake="hogehoge" name="facheck1" value="$addr">
-->
<INPUT type="hidden" fake="hogehoge" name="facheck1" value="$chcode">
<!--
<INPUT type="hidden" fake="hogehoge" name="facheck1" value="$date_num">
-->
<INPUT type="hidden" fake="hogehoge" name="dammycode" value="$addr">
<INPUT type="hidden" name="facheck3" value="$rport">
<TABLE>
  <TBODY>
    <TR>
      <TD><B>お名前</B></TD>
      <TD><INPUT type="text" name="name" size="26" value="" onchange="cook1()"></TD>
    </TR>    
    <TR>
      <TD><B>メール</B></TD>
      <TD><INPUT type="text" name="email" size="26" value="" onchange="cook2()"></TD>
    </TR>
    <TR>
      <TD><B>題　名</B></TD>
      <TD><INPUT type="text" name="subject" size="48" value="$r_subject" ></TD>
    </TR>
    <TR>
      <TD colspan="2"><B>メッセージ</B>　<INPUT type="checkbox" name="link" value="1" checked> <B>URL自動リンク</B><BR>
      <TEXTAREA name="value" rows="10" cols="72" wrap="off" ></TEXTAREA></TD>
    </TR>
    <TR>
      <TD><B>ＨＯＭＥ</B></TD>
      <TD><INPUT type="text" name="website" size="70" value="http://"  onchange="cook3()"></TD>
    </TR>
    <TR>
      <TD><B>パスワード</B></TD>
      <TD><INPUT type="password" name="spwd" size="12" maxlength="8"  onchange="cook4()"> &lt;&lt;$c_color半角英数8文字以内で必ず記入</font></TD>
    </TR>
_HTML_

if ($pict) { # 対フェイザーがオンの場合の表示
    print "<TR><TD><B>右の数字</B></TD><TD><INPUT type=\"text\" size=12 name=\"facheck2\">　<IMG SRC=\"$himicode\" ALIGN=TOP>　&lt;&lt;$c_color半角英数で記入</font></TD>\n";
    print "</TR>\n";
}
print "    <TR>\n      <TD><B>文字色</B></TD>\n      <TD>\n";
print "      <input type=radio name=color value=\"0\" checked><font color=\"$colors[0]\">■</font>\n";
for ($i = 1; $i < @colors; $i++) {
    print "      <input type=radio name=color value=\"$i\"><font color=\"$colors[$i]\">■</font>\n";
}
print "    </TD>\n    </TR>\n";
print <<"_HTML_";
    <TR>
      <TD colspan="2">
      <BR>
      <INPUT type="submit" value="投稿 / リロード"  onclick="cook5()">　<INPUT type="reset" value="リセット" ><BR>
_HTML_

if ($DispID) {
  print "      <BR>\n      <HR size=\"1\" noshade>\n";
  print "      ■毎回同一のお名前とパスワードを入力することによって、同一のＩＤを生成します<BR>\n";
  print "      ■管理者名・管理者ＩＤは掲示板の左上に表\示されています<BR>\n";
  if ($use_id) { print "      ■ＩＤを登録すれば、好きなＩＤを利用することができます<BR>\n"; }
  print "      <HR size=\"1\" noshade>\n";
}

print "      </TD>\n    </TR>\n  </TBODY>\n</TABLE>\n";

if (($FORM{'mode'} eq 'res') && ($FORM{'res'}) && ($FORM{'res_code'}) && ($FORM{'do'} eq '')) {

print <<"_HTML_";
<INPUT type="hidden" name="mode" value="res">
<INPUT type="hidden" name="res" value="$FORM{'res'}">
<INPUT type="hidden" name="res_code" value="$FORM{'res_code'}">
<INPUT type="hidden" name="do" value="reload">
_HTML_
}
print "</FORM>";
}

#--------- ログファイルの書き込み -------------------------------#

sub write_log {

  if ($pcheck_flag != 1) { # 変数の取得　アクセス時にログを取っていなかった場合
    $via    = $ENV{'HTTP_VIA'};
    $xfor   = $ENV{'HTTP_X_FORWARDED_FOR'};
    $for    = $ENV{'HTTP_FORWARDED'};
    $agent  = $ENV{'HTTP_USER_AGENT'};
  }  
  if ($alog != 1) {
    $value_size = length($via);
    if ( $value_size > 150) { &error('x'); }
    $value_size = length($for);
    if ( $value_size > 150) { &error('x'); }
    $value_size = length($agent);
    if ( $value_size > 150) { &error('x'); }  
  }  
  if ( ($kyoka eq "") && ($proxy == 1) ) {
    &proxy;
  } elsif ( ($host !~ /$kyoka/) && ($proxy == 1) ) {
    &proxy;
  }

&code_check;

if ($FORM{'spwd'} =~ /\W/ || length($FORM{'spwd'}) > 8) {
    &errorz('入力ミス','削除パスワード欄は8文字以内の半角英数字で記入して下さい。<br>これは記事の削除時に利用するものです。');
}

# 書き込み内容の容量チェック
  if ($max_s) {
    $value_size = length($FORM{'subject'});
    if ($value_size > $max_s) {
      &errorz('タイトルが長過ぎます（＾＾；',"タイトルが最大記録サイズ$max_sを超えています。現在$value_sizeサイズです。");
    }
  }
  if ($max_n) {
    $value_size = length($FORM{'name'});
    if ($value_size > $max_n) {
      &errorz('お名前が長過ぎます（＾＾；',"お名前が最大記録サイズ$max_nを超えています。現在$value_sizeサイズです。");
    }
  }
  if ($max_v) {
    $value_size = length($FORM{'value'});
    if ($value_size > $max_v) {
      &errorz('内容が長過ぎます（＾＾；',"書き込み内容が最大記録サイズ$max_vを超えています。現在$value_sizeサイズです。");
    }
  }
  if ($max_line) {
    $value_size = ($FORM{'value'} =~ tr/\r/\r/) + 1; # \r の数を数える
    if ($value_size > $max_line) {
      &errorz('行数が多過ぎです（＾＾；',"書き込み内容の行数が最大行数$max_lineを超えています。現在$value_sizeサイズです。");
    }
  }
# 行数チェック後にタグへ置換する
$FORM{'value'} =~ s/\r/<br>/g;
  
  if ($max_mail) {
    $value_size = length($FORM{'email'});
    if ($value_size > $max_mail) {
      &errorz('メールアドレスが長過ぎます（＾＾；',"メールアドレスが最大記録サイズ$max_mail文字を超えています。現在$value_sizeサイズです。");
    }
  }
  if ($max_home) {
    $value_size = length($FORM{'website'});
    if ($value_size > $max_home) {
      &errorz('ホームページアドレスが長過ぎます（＾＾；',"ホームページアドレスが最大記録サイズ$max_home文字を超えています。現在$value_sizeサイズです。");
    }
  }

  # 偽名拒否の処理
  if ($gimei) {
    if ($g_length == 1) {
      if (crypt($FORM{'spwd'}, substr($password,$salt,2)) ne $password) {
        @adminword = split(/\s+/ , $admin);
        foreach $admin (@adminword) {
          if ($FORM{'name'} =~ /$admin/i) {
            &jump;
          }
        }
      }
     }
     else {
       $idflag = 0;
       if (($FORM{'name'} =~ /\W/) || ($master =~ /\W/)) { $idflag = 1; }
    
         if (crypt($FORM{'spwd'}, substr($password,$salt,2)) ne $password) {
            @adminword = split(/\s+/ , $admin);
            foreach $admin (@adminword) {
              if (($idflag == 1) && ($FORM{'name'} eq "$admin")) {
                &jump;
              }
              elsif (($idflag == 0) && ($FORM{'name'} =~ /^$admin$/i)) {
                &jump;
              }
            }
         }
     }
  }

if (($d_check) || ($p_check)) {
  &dp_check;
  }

$agent =~ s/,/./g;
$via =~ s/,/./g;
$for =~ s/,/./g;
$trueip =~ s/,/./g;

$idflag = 0;
if (($FORM{'name'} =~ /\W/) || ($master =~ /\W/)) { $idflag = 1; }

if ((crypt($FORM{'spwd'}, substr($password,$salt,2)) eq $password ) && ($idflag == 1) && ($FORM{'name'} eq "$master")) {
    $spwd = "$master_id";
  } elsif ((crypt($FORM{'spwd'}, substr($password,$salt,2)) eq $password ) && ($idflag == 0) && ($FORM{'name'} =~ /^$master$/i)) {
    $spwd = "$master_id";
  }  
    elsif (($use_id == 1) && ($FORM{'spwd'})) {
      $idpwd = crypt($FORM{'spwd'}, &mkSalt($FORM{'name'}.$FORM{'spwd'}.$idps) );
      open(ID,"$idlist") || die "Can't Open ID List: $!\n";
        while (<ID>) {
         ($number0, $id, $date0, $idpass0, $name0, $host0, $addr0, $via0, $for0, $trueip0, $agent0, $checkcode) = split(/\,/,);
                  
         if (($FORM{'name'} =~ /\W/) || ($name0 =~ /\W/)) {
           if (($FORM{'name'} eq $name0) && ($idpwd eq $idpass0)) {
             $spwd = "$id\:$idpwd";
             last;
           }
         }
         elsif (($FORM{'name'} =~ /^$name0$/i) && ($idpwd eq $idpass0)) {
           $spwd = "$id\:$idpwd";
           last;
         }
        }
       close(ID);
       if ($spwd eq "") {
         if ($FORM{'spwd'}) { 
           $spwd = crypt($FORM{'spwd'}, &mkSalt($FORM{'name'}.$FORM{'spwd'}.$idps) );
         } else {
           $spwd = '';
         }
       }
  } elsif ($FORM{'spwd'}) {
    $spwd = crypt($FORM{'spwd'}, &mkSalt($FORM{'name'}.$FORM{'spwd'}.$idps) );
  } else {
    $spwd = '';
  }

if (($FORM{'subject'} eq '') || ($FORM{'subject'} eq ' ') || ($FORM{'subject'} eq '　')) { $FORM{'subject'} = "(No Subject)"; }

#追加した部分（色変更）

if (($FORM{'color'} =~ /\D/) || ($FORM{'color'} < 0) || ($FORM{'color'} > @colors)) {
    &error('x');
}
$postcolor = $colors[$FORM{'color'}];
if ($postcolor) { $FORM{'value'} = "<font color=\"$postcolor\">$FORM{'value'}</font>"; }

#####

if ($FORM{'mode'} eq 'res') { 
$res_num = $FORM{'res'};
$res_code = $FORM{'res_code'};
&write_log2;
}

# ログファイル読み込み
  if ( !open(DB,"$file") ) { &error('0'); }
  @lines = <DB>;
  close(DB);

  $k = 1;
  $delete = 0;
  foreach $line (@lines) {
    #$i++;
     ($number, $spwd_d, $date, $name, $email, $value_d, $subject, $link, $host_d, $addr_d, $via_d, $for_d, $trueip_d, $agent_d, $website_d, $checkcode, $r_total) = split(/\,/,$line);
    
    if ($r_total) {
      $k++;
      if ($k > $max) { $delete = 1; }
      }
    if ($delete == 1) { last; }
    push(@new, $line);
  }

  $value = "$date_num\,$spwd\,$date_now\,$FORM{'name'}\,$FORM{'email'}\,$FORM{'value'}\,$FORM{'subject'}\,$FORM{'link'}\,$host\,$addr\,$via\,$for\,$trueip\,$agent\,$FORM{'website'}\,$dukecheck\,0\n";

  unshift(@new, $value);
  if ( !open(DB,">>$file") ) { &error('0'); }
    if ($use_flock == 1) {
      flock(DB, 2);
    }
    truncate(DB, 0);
    print DB @new;
    close(DB);

#投稿されたチェックコードを記録する
  if ( !open(LOG,"$code_log") ) { &error('0'); }
  @lines = <LOG>;
  close(LOG);
  unshift(@lines, "$dukecheck\n");
  pop @lines while @lines > $maxline;
  if ( !open(LOG,">$code_log") ) { &error('0'); }
  print LOG @lines;
  close(LOG);

}

#-------- レスの書き込み-----------#

sub write_log2 {

#
# ここでレス元サーチをしてその下にレスを入れる。
# 

$data_num = 0;

# ログファイル読み込み
  if ( !open(DB,"$file") ) { &error('0'); }
  @lines = <DB>;
  close(DB);

foreach $lines (@lines) {

$data_num++;

  ($number, $spwd_d, $date, $name, $email, $value, $subject, $link, $host_d, $addr_d, $via_d, $for_d, $trueip_d, $agent_d, $website, $checkcode, $r_total) = split(/\,/,$lines);

if (($number eq $res_num) && ($checkcode eq $res_code)) {
  if (($r_total > $max_res) && ($max_res)) { &errorz('返信数オーバー','返信が制限数を超えています。新しくスレッドを作成してください。'); }
  $tdata_num = $data_num - 1;
  $data_num = $data_num + $r_total;
  $r_total++;

  $lines = "$number\,$spwd_d\,$date\,$name\,$email\,$value\,$subject\,$link\,$host_d\,$addr_d\,$via_d\,$for_d\,$trueip_d\,$agent_d\,$website\,$checkcode\,$r_total\n"; 
  if (($FORM{'subject'} eq '') || ($FORM{'subject'} eq ' ') || ($FORM{'subject'} eq '　')) { $FORM{'subject'} = "(No Subject)";  }
  $value = "$date_num\,$spwd\,$date_now\,$FORM{'name'}\,$FORM{'email'}\,$FORM{'value'}\,$FORM{'subject'}\,$FORM{'link'}\,$host\,$addr\,$via\,$for\,$trueip\,$agent\,$FORM{'website'}\,$dukecheck\,\,\n";

  splice( @lines, $data_num, 0, "$value" );

if (($resup == 1) && ($data_num != 1)) {
  $data_num++;
  for ($l = $tdata_num; $l < $data_num; $l++) {
    push(@uplist, $lines[$l]);
  }
  splice( @lines, $tdata_num, $data_num - $tdata_num );
  @uplist = reverse( @uplist );
  for ($l = 0; $l < @uplist; $l++) {
    unshift( @lines, $uplist[$l]);
  }
}
  if ( !open(DB,">>$file") ) { &error('0'); }
    if ($use_flock == 1) {
      flock(DB, 2);
    }
    truncate(DB, 0);
    print DB @lines;
    close(DB);
         
    #投稿されたチェックコードを記録する
 if ( !open(LOG,"$code_log") ) { &error('0'); }
   @lines = <LOG>;
   close(LOG);
   unshift(@lines, "$dukecheck\n");
   pop @lines while @lines > $maxline;
   if ( !open(LOG,">$code_log") ) { &error('0'); }
   print LOG @lines;
   close(LOG);
    
    &html;
  
    }
  }
}

#--- 管理者モード ---------------------#

sub admin {

print <<"_HTML_";
Content-type: text/html

<HTML>
<HEAD><TITLE>管理者モード</TITLE></HEAD>
$body
$style
<H3>管理者モード</H3>
<FORM method="POST" action="$reload">
<input type=hidden name="action" value="ad">
管理者モード：
<SELECT NAME="admin">
<OPTION value="change">パスワード変更
<OPTION value="cut" SELECTED>記事一覧
<OPTION value="remid1">ＩＤ一覧
<OPTION value="kick">制限モード
<OPTION value="idps">ＩＤ暗号化パス変更</SELECT>
 <input type="password" name="pwd" size="10">
<INPUT type="submit" value="変更/一覧/設定"></FORM><p>
<a href="$reload">掲示板へ戻る</a>　<a href="$home">ホームへ</a></p>
</body></HTML><hr>
_HTML_

exit;
}

#-------- 管理者パスワード登録＆暗号化 -----------------------#

sub password {
  $psold = $FORM{'password_old'};
  $pas1 = $FORM{'password'};
  $pas2 = $FORM{'password2'};
  
  print <<"_HTML_";
Content-type: text/html

<HTML>
<HEAD>
<TITLE>$title</TITLE>
$style
</HEAD>
$body
<H2>管理者パスワードの設定\／変更画面</H2>
_HTML_
  if ($start == 1 && $pas1 eq '') {
    print "管理者パスワードをこのページで設定\します。<P>\n";
  } elsif ($pas1 =~ /\W/) {
    print "<FONT COLOR=red>新パスワードに英数字以外の文字が含まれています。</FONT><P>\n";
  } elsif ( $pas1 ne '' && $pas1 ne $pas2 ){
    print "<FONT COLOR=red>確認のために入力された新パスワードが一致しません。</FONT><P>\n";
  } elsif ( $start != 1 && $psold eq '' ) {
    print "<FONT COLOR=red>旧パスワードも入力して下さい。</FONT><P>\n";
  } elsif ( $start != 1 && (crypt($psold, substr($password, $salt, 2) ) ne $password) ){
    print "<FONT COLOR=red>旧パスワードが認証されませんでした。</FONT><P>\n";
  } elsif ( ($start == 1) && ($FORM{'id_password'} eq '') || ($FORM{'id_password'} =~ /\W/) ){
    print "<FONT COLOR=red>ＩＤ暗号化用のパスワードが入力されていないか、英数字以外の文字が含まれています。</FONT><P>\n";
  } else {
    $now = time;
    ($p1, $p2) = unpack("C2", $now);
    $wk = $now / (60 * 60 * 24 * 7) + $p1 + $p2 - 8;
    @saltset = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/');
    $nsalt = $saltset[$wk % 64] . $saltset[$now % 64];
    $pwd = crypt($FORM{'password'}, $nsalt);
    if ($FORM{'id_password'} eq '') {
      $pwd2 = $idps;
    } else {
      $pwd2 = crypt($FORM{'id_password'}, $nsalt);
    }
    if ( !open(DB,">$pass") ) { &error('0'); }
    print DB "crypt_password:$pwd\n";
    print DB "id_password:$pwd2\n";
    close(DB);
    print "<FONT COLOR=blue size=\"+1\">管理者パスワードが設定\されました。<BR><A HREF=\"$reload\">[ＮＥＸＴ]</A>←をクリックして下さい。</FONT><P>再度変更する場合は下記フォームで再入力しなおして下さい。<P>\n";
  }
  print "<FORM method=\"POST\" action=\"$reload\">\n";
  print "<input type=hidden name=\"action\" value=\"pas\">";
  print "<INPUT type=\"hidden\" name=\"papost\" value=\"pcode\">\n";
  if ($start != 1) {
    print "旧パスワード <INPUT type=\"password\" name=\"password_old\" size=\"8\" maxlength=\"8\"><BR>\n";
  } else {
    print "ＩＤ暗号化用　<INPUT type=\"password\" name=\"id_password\" size=\"8\" maxlength=\"8\">（ＩＤ暗号化用パス・半角英数８文字以内。覚える必要なし。<FONT COLOR=red>一度設定したら必要な時以外変更しないで下さい</FONT>）<BR>\n";
  }
print <<"_HTML_";
新パスワード <INPUT type="password" name="password" size="8" maxlength="8">（半角英数８文字以内）<BR>
新パスワード <INPUT type="password" name="password2" size="8" maxlength="8">（確認のため上と同じパスをもう一度）<P>
<INPUT type="submit" value="     登録     ">
</FORM><P>
</BODY>
</HTML>
_HTML_
exit;
}

#-------- ＩＤ暗号化パスワード変更画面 --------------------------#

sub idps {

print <<"_HTML_";
Content-type: text/html

<HTML>
<HEAD>
<TITLE>$title</TITLE>
$style
</HEAD>
$body
<H2>ＩＤ暗号化用パス変更画面</H2>
<FONT COLOR=red>注意：必要な時以外は変更しないで下さい。認識ＩＤ表\示と固定ＩＤの認証が変わってしまいます。</FONT><P>
_HTML_

if ($FORM{'admin'} ne 'idps2') {
    print "ＩＤ暗号化パスをこのページで設定\します。<P>\n";
} elsif ( ($FORM{'admin'} eq 'idps2') && ($FORM{'new_idps'} eq '') ) {
    print "<FONT COLOR=red>ＩＤ暗号化用パスが入力されていません。</FONT><P>\n";
} elsif ( ($FORM{'admin'} eq 'idps2') && ($FORM{'new_idps'} =~ /\W/) ) {
    print "<FONT COLOR=red>ＩＤ暗号化用パスに半角英数字以外の文字が含まれています。</FONT><P>\n";
} else {
    $now = time;
    ($p1, $p2) = unpack("C2", $now);
    $wk = $now / (60 * 60 * 24 * 7) + $p1 + $p2 - 8;
    @saltset = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/');
    $nsalt = $saltset[$wk % 64] . $saltset[$now % 64];
    $pwd2 = crypt($FORM{'new_idps'}, $nsalt);
    if ( !open(DB,">$pass") ) { &error('0'); }
    print DB "crypt_password:$password\n";
    print DB "id_password:$pwd2\n";
    close(DB);
    print "<FONT COLOR=blue size=\"+1\">ＩＤ暗号化用パスワードが設定\されました。<BR><A HREF=\"$reload\">[ＮＥＸＴ]</A>←をクリックして下さい。</FONT><P>再度変更する場合は下記フォームで再入力しなおして下さい。<P>\n";
}

print <<"_HTML_";
<FORM method="POST" action="$reload">
<input type="hidden" name="admin" value="idps2">
<input type="hidden" name="action" value="idps">
管理者パスワード <input type="password" name="password" size="8" maxlength="8">（半角英数８文字以内）<BR>
ＩＤ暗号化用パス　<input type="password" name="new_idps" size="8" maxlength="8">（半角英数８文字以内）<P>
<INPUT type="submit" value="     登録     ">
</FORM><P>
</BODY>
</HTML>
_HTML_
exit;
}

#-------- 認識ＩＤ用暗号処理（削除パスを暗号化） ----------------#

sub mkSalt {
  local($t, $sum, @salt ) = @_;
  @salt = split(//, './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
  if ($t) {
    $sum = unpack("%12C*", $t);
  } else { # ハンドルが空の場合
    return 'No';
  }
  $salt[$sum % 64] . $salt[int($sum/64) % 64];
}


#----------- ダブルポスト＆連続投稿チェック --------------------#

sub dp_check {
if ($dplev == 1) {
  $i = 1;
  $total = "";
  open(LOG,"$file") || die "Can't Open LOG: $!\n";
  while (<LOG>) {

    ($number0, $spwd0, $date0, $name0, $email0, $value0, $subject0, $link0, $host0, $addr0, $via0, $for0, $trueip0, $agent0, $website0, $checkcode0, $r_total0) = split(/\,/,);

    if ($r_total0 =~ /\d/ && $r_total0 == 0) { push(@list , $_); }
    elsif ($r_total0 ne "") { $total = $r_total0; push(@list , $_); }
    elsif ($i != $total) { $i++; }
    elsif ($i == $total) { push(@list , $_); $i = 1; }
  
  }
  close(LOG);
}
elsif ($dplev == 2) {
  open(LOG,"$file") || die "Can't Open LOG: $!\n";
  @list = <LOG>;
  close(LOG);
}

@sort = reverse sort { (split(/\,/,$a))[0] <=> (split(/\,/,$b))[0] } @list;

for ($i=0; $i < $dc; $i++) {

 ($number0,$d,$d,$d,$d,$value0,$d,$d,$host0,$d,$d,$d,$d,$d,$d,$checkcode0,$d) = split(/\,/,$sort[$i]);
    if ( ($d_check) && substr($FORM{'value'},0,$checklength) eq substr($value0,0,$checklength) ) {
      &errorz('二重投稿です（^^；',"その内容はすでに投稿済みです。");
    }
 if ($p_check) { 
  if ($ctimer == 0) {
      if (($host eq $host0) && ($date_num > $number0) && ($date_num - $number0 < $timer) ) {
        &errorz('少しお待ち下さい（^^；',"悪戯対策のため同一ホストからの$rtimer分以内の連続投稿はできなくなっています。");
      }
    }
    if ($ctimer == 1) {
      if (($date_num > $number0) && ($date_num - $number0 < $timer) ) {
        &errorz('少しお待ち下さい（^^；',"悪戯対策のため直前の投稿から$rtimer分以内の連続投稿はできなくなっています。");
      }
    }
  }
 }

}

#----- コードチェック --------------------------------------#

sub code_check {

  #暗号コードを戻す
  $i = 0;
  $dukecheck = $FORM{'facheck1'};
  $dukecheck=~ s/[\da-f]{2}/sprintf("%c",hex($&)^ord($key[$i++ % @key]))/ige;
  $dukecheck = ( $dukecheck / $num2 ) - $num1;
  if ( $dukecheck < 101000000) {
    &error('x');
  }
  if ( $dukecheck >= $date_num) {
    &errorz('チェックコードエラー','再度掲示板を読み込みなおしてください。年を跨いでるのかも(^^;');
  }
  if (($date_num > $dukecheck) && (($date_num - $dukecheck) < 20)) {
    &errorz('チェックコードエラー','最初に掲示板にアクセスしてから実際に投稿するまでの間隔は数十秒
あけて下さい。<BR>ブラウザの[戻る]ボタンを押して前の画面に戻り少し時間をおいて投稿（登録）ボタンを押し直し
て下さい。');
  }
  if ( ($date_num - $dukecheck) > 30000) {
    &errorz('チェックコードエラー','チェックコードが古すぎます。<BR>再度掲示板を読み込みなおしてください。');
  }
  $dukecheck = sprintf("%010d", $dukecheck);
  $str1 = substr("$dukecheck" , -6, 2);
  $str2 = substr("$dukecheck" , -8, 2);
  if ($str1 > 23) {
    &error('x');
  }
  if ($str2 > 31) {
    &error('x');
  }

if ($pict) { # 対フェイザーオンの場合は実際に発行されたコードかどうか照合
    if ($FORM{'facheck2'} eq '') {
      &errorz('チェックコードエラー',"投稿コードが入力されてません(^^;;");
    }  
    $dukecheck = $FORM{'facheck2'} . $FORM{'facheck3'}; 
    if ( !open(DB,"$himicode_log") ) { &error('0'); }
    @lines = <DB>;
    close(DB);

    $dukecheck = ($dukecheck + $num1) * $num2;
    # 入力されたひみこーどを任意のキーで暗号化
    $i = 0;
    $dukecheck =~ s/./sprintf("%02x",ord($&)^ord($key[$i++ % @key]))/ge;
    
    $himikocheck=0;
    foreach $line (@lines) {
      chop($line);
      if ($dukecheck eq $line) {
        $himikocheck=1;
      }
    }      
    if ($himikocheck != 1) {
      &error('x');    
    }
  }  

if ( !open(DB,"$code_log") ) { &error('0'); }
  @lines = <DB>;
  close(DB);
  foreach $line (@lines) {
    chop($line);
    if ($dukecheck eq $line) {
      &errorz('チェックコードエラー',"そのコードはすでに使われています。<BR>もう一度アクセスし直して下さい。");
    }
  }
}

#---------------------- 削除処理 -----------------------------#

sub delete {

if (($FORM{'spwd'} eq '') && ($FORM{'pwd'} eq '')) { &errorz('入力ミス','パスワードが入力されていません'); }
elsif ($FORM{'spwd'} =~ /\W/ || length($FORM{'spwd'}) > 8) { &errorz('入力ミス','パスワードは8文字以内の半角英数字で記入して下さい'); }
elsif ($FORM{'del'} eq '') { &errorz('削除記事チェックミス','削除対象の記事にチェックを入れてください'); }
unless (($FORM{'del'} =~ /sr:\w/) || ($FORM{'del'} =~ /\w/)) { &html; }

($sr_num, $del_num) = split(/:/, $FORM{'del'});

# パスワードチェック

$delflag = 0;
$i = 0;

if ($sr_num eq 'sr') {

  if ( !open(DB,"$file") ) { &error('0'); }
  @lines = <DB>;
  close(DB);

  foreach $line (@lines) {
    ($number,$spwd,$date,$name,$email,$value,$subject,$link,$host,$addr,$via,$for,$trueip,$agent,$website,$dukecheck,$r_total) = split(/\,/,$line);
    $i++;
    if ($spwd =~ /\:/) {
      ($d, $spwd) = split(/:/,$spwd);
    }
    if ($del_num eq $number) {  
    if ( (crypt($FORM{'spwd'}, substr($password, $salt, 2) ) eq $password) ||
         ($spwd && (crypt($FORM{'spwd'}, $spwd) eq $spwd ) ) || (crypt( $FORM{'pwd'}, substr($password, $salt, 2) ) eq $password) ) {
         $line = '';
      $z = $i + $r_total;
      splice( @lines, $i, $z - $i );      
      $delflag = 1;
      last;
      }
    }
  }
}
elsif (($sr_num) && ($del_num)) {
  
  if ( !open(DB,"$file") ) { &error('0'); }
  @lines = <DB>;
  close(DB);

  foreach $line (@lines) {
    ($number,$spwd,$date,$name,$email,$value,$subject,$link,$host,$addr,$via,$for,$trueip,$agent,$website,$dukecheck,$r_total) = split(/\,/,$line);
     
    if ($sr_num eq $number) {
      $r_total--;
      $line = "$number\,$spwd\,$date\,$name\,$email\,$value\,$subject\,$link\,$host\,$addr\,$via\,$for\,$trueip\,$agent\,$website\,$dukecheck\,$r_total\n";
    }
    if ($del_num eq $number) {
      if ($spwd =~ /\:/) {
       ($d, $spwd) = split(/:/,$spwd);
      }  
      if ( (crypt($FORM{'spwd'}, substr($password, $salt, 2) ) eq $password) ||
         ($spwd && (crypt($FORM{'spwd'}, $spwd) eq $spwd ) ) || (crypt( $FORM{'pwd'}, substr($password, $salt, 2) ) eq $password) ) {
         $line = "";
      $delflag = 1;
      last;
      }
    }
  }
}
 if ($delflag == 1) {
   if ( !open(DB,">>$file") ) { &error('0'); }
    if ($use_flock == 1) {
      flock(DB, 2);
    }
    truncate(DB, 0);
    print DB @lines;
    close(DB);
 }
}

#------------- 掲示板の説明  ----------------#

sub how {
print <<"_HTML_";
Content-type: text/html

<HTML>
<HEAD><TITLE>掲示板の使い方</TITLE></HEAD>
$body
$style
<a href="$reload">掲示板へ戻る</a>　<a href="$home">ホームへ</a>
<center>
<H3>掲示板の使い方</H3>
<TABLE bordercolor="$tbrcolor" cellspacing="0" cellpadding="4" width="90%" bgcolor="$tbgcolor" border="1">
  <TR><TD>
      <BLOCKQUOTE><BR>
      <OL>
<LI>投稿するために必要な項目は<b>「お名前」</b>と<b>「メッセージ」</b>です。その他の項目は任意です。<p>
<LI>投稿時に<b>「パスワード」</b>を入力しておくと、後に投稿記事を削除することができます。<p>
<LI>記事に<b>「返信」</b>をするには、返信対象の記事の右上にある<b>「返信する」</b>をクリックすると返信フォームが表\示されます。<p>
<LI>記事を削除するには、対象の記事の左上にあるチェックボックスにチェックをして下方にある削除用フォームから削除することができます。<p>
<LI>管理者のパスワードを使用すれば、どの記事でも削除することができます。他に管理者モード（記事一覧）からも削除することが可能\です。<p>
<LI>親記事を削除すると、それに対する返信記事も一緒に削除されます。<p>
_HTML_

if ($tag == 1) {
  print "<LI><b>「タグの使用」</b>が可能です。タグを使用する場合は<b>「自動ＵＲＬリンク」</b>のチェックをはずしてください。<p>\n";
}
else {
  print "<LI><b>「タグの使用」</b>は一切できません。<p>\n";
}
if ($DispID == 1) {
  print "<LI>投稿時の<b>「お名前」</b>と<b>「パスワード」</b>を固定することで、個別の<b>「認識ＩＤ」</b>を生成します（かたり防止）。<p>\n";
  print "<LI>管理者のＩＤは <b>[ $master_id ]</b> です。騙りに気をつけましょう。<p>\n";
}
if ($use_id == 1) {
  print "<LI><b>「ＩＤ登録・削除」</b>から、<b>「固定ＩＤ」</b>を登録することができます。<p>\n";
  print "<LI>登録したＩＤを削除するには<b>「ＩＤ登録･削除」</b>から、登録した<b>「お名前」「ＩＤ」「パスワード」</b>を入力して削除してください。<p>\n";
  print "<LI>管理者は<b>「管理者モード（ＩＤ一覧）」</b>から登録された<b>「固定ＩＤの一覧」</b>を見ることができ、削除することが可能\です。<p>\n";
}
print <<"_HTML_";
      </BLOCKQUOTE>
      </OL>
    </TD></TR>
</TABLE>
</center>
</body>
</html>
_HTML_

exit;
}

#--- 投稿者一覧表示 --------------------------------#

sub remove1 {
  if ( !open(DB,"$file") ) { &error('0'); }
    @lines = <DB>;
  close(DB);

  print <<"_HTML_";
Content-type: text/html

<HTML>
<HEAD>
<TITLE>$title</TITLE>
$style
</HEAD>
$body
<FONT size="+1"><B>投稿者一覧モード（記事削除もできます）</B></FONT>  [<A href="$reload">戻る</A>]<P>
- 親記事には★マークがつきます -<br>
<FORM method="POST" action="$reload">
<input type=hidden name="action" value="osr">
<PRE>
        登録日               投稿者(認識ID)                  タイトル               アクセスデータ(REMOTE_HOST - REMOTE_ADDR - HTTP_VIA - HTTP_FORWARDED - TrueIP - USER_AGENT)<hr>
_HTML_
  foreach $line (@lines) { ($number,$spwd,$date,$name,$email,$value,$subject,$link,$host,$addr,$via,$for,$trueip,$agent,$website,$dukecheck,$r_total) = split(/\,/,$line);
    chop($subject) if ($subject =~ /\r/);
    $name  =~ s/</&lt;/ig;
    $name  =~ s/>/&gt;/ig;
    $subject  =~ s/</&lt;/ig;
    $subject  =~ s/>/&gt;/ig;
    $via  =~ s/</&lt;/ig;
    $via  =~ s/>/&gt;/ig;
    $for  =~ s/</&lt;/ig;
    $for  =~ s/>/&gt;/ig;
    $trueip  =~ s/</&lt;/ig;
    $trueip  =~ s/>/&gt;/ig;
    $agent  =~ s/</&lt;/ig;
    $agent  =~ s/>/&gt;/ig;
    ($spwd, $d) = split(/:/, $spwd);
    
    $i1 = length($name);
    if ($i1 > 14) {
      $name = substr($name, 0, 14);
    } elsif ($i1 < 14) {
      $blank = ' ' x (14 - $i1);
      $name = $name . $blank;
    }
    $i2 = length($subject);
    if ($i2 > 20) {
      $subject = substr($subject, 0, 20);
    } elsif ($i2 < 20) {
      $blank = ' ' x (20 - $i2);
      $subject = $subject . $blank;
    }
    $spwd =~ s/^.*(.{11})$/$1/;
    $i3 = length($spwd);
    $blank = '-' x (13 - $i3);
    $spwd = $spwd . $blank;
  if ($r_total) {  
    print "<INPUT type=\"checkbox\" name=\"del\" value=\"sr:$number\">";
    print " ★ $date - $name($spwd) - $subject - $host - $addr - $via - $for - $trueip - $agent\n";
    $temp_number = $number;
    }
  else {
    print "<INPUT type=\"checkbox\" name=\"del\" value=\"$temp_number:$number\">";
    print "    $date - $name($spwd) - $subject - $host - $addr - $via - $for - $trueip - $agent\n";
    }
  }
print <<"_HTML_";
</PRE><P>
<INPUT type="hidden" name="pwd" value="$FORM{'pwd'}">
<INPUT type="submit" value="     削除     "><INPUT type="reset" value="リセット">
</FORM><P>
</BODY>
</HTML>
_HTML_
}


#--- proxyアクセスの排除 --------------------------------#

sub proxy {
  if ($plevel == 1) { # 制限レベル「弱」の場合
    if ($xfor !~ s/^(\d+)\.(\d+)\.(\d+)\.(\d+)(\D*).*/$1.$2.$3.$4/) { # IP漏れしている場合は許可
      if ($host =~ /squid|^firewall|proxy|cache|delegate|^dns|keeper|^mail|^www|^ns\d{0,2}\.|us$|uk$|edu$|com$|org$|net$|at$|au$|ca$|ch$|de$|dk$|fi$|fr$|it$|il$|kr$|nl$|pt$|tw$/i) {
        &error('kusi');
      }
      if ($via  ne "") { &error('kusi'); }
      if ($xfor ne "") { &error('kusi'); }
      if ($for  ne "") { &error('kusi'); }
      if ($agent =~ /via|squid|delegate|httpd|proxy|cache/i){ &error('kusi'); }
    }
  } else  { # 制限レベル「強」の場合
    if ($host !~ /jp$/i) { # jpドメインじゃない場合（ＩＰ串も）アウト！
      &error('kusi');
    } 
    if ($host =~ /squid|^firewall|proxy|cache|delegate|^dns|keeper|^mail|^www|^ns\d{0,2}\./i) {
      &error('kusi');
    }
    if ($via  ne "") { &error('kusi'); }
    if ($xfor ne "") { &error('kusi'); }
    if ($for  ne "") { &error('kusi'); }
    if ($agent=~ /via|squid|delegate|httpd|proxy|cache/i) { &error('kusi');}
    if ($ENV{'HTTP_PROXY_CONNECTION'} ne "") { &error('kusi'); }
    if ($ENV{'HTTP_CACHE_INFO'}       ne "") { &error('kusi'); }
  }
}

#--- 指定ホストキック --------------------------------#

sub hostcheck{
  if ( !open(DB,"$hostlist") ) { &error('0'); }
    @lines = <DB>;
  close(DB);
  foreach $line (@lines) {
    chop($line);
    if ($host =~ /$line/) {
      &jump;
    }
  }
}

#--- キック用ジャンプ処理 --------------------------------#

sub jump {
  print "Content-type: text/html\n";
  print "Location: $jumpurl\n\n";
  exit;
}

#--- キック用ホスト登録画面 --------------------------------#

sub kickhost{
  $hostdate = $FORM{'hostdate'};
  $touroku = $FORM{'touroku'};
  $kirikae = $FORM{'kirikae'};
  if ( !open(DB,"$hostlist") ) { &error('0'); }
  @lines = <DB>;
  close(DB);
  $phas = shift(@lines);  
  if ($kirikae eq '3') {
    if ( !open(DB,">$hostlist") ) { &error('0'); }
    print DB "phaser_on\n";
    foreach $line (@lines) {
      print DB "$line";
    }
    close(DB);
    $pict = 1;
  }elsif ($kirikae eq '4') {
    if ( !open(DB,">$hostlist") ) { &error('0'); }
    print DB "phaser_off\n";
    foreach $line (@lines) {
      print DB "$line";
    }
    close(DB);
    $pict = 0;
  }
  print <<"_HTML_";
Content-type: text/html

<HTML>
<HEAD>
<TITLE>対フェイザースイッチ切り替え＆拒否ホスト登録モード</TITLE>
$style
</HEAD>
$body
<CENTER><BR>
<H3>対フェイザースイッチ切り替えモード</H3>
_HTML_
  if ($pict) {
    print "<FONT COLOR=red>現在対フェイザーはオン（画像式チェックコード）です。</FONT>\n";
  } else {
    print "<FONT COLOR=red>現在対フェイザーはオフ（ノーマルチェックコード）です。</FONT>\n";
  } 
  print "[<a href=\"$reload\">戻る</a>]<BR>";
  print <<"_HTML_";
<FORM method="POST" action="$reload">
<input type=hidden name="action" value="kickout">
<INPUT type="hidden" name="pwd" value="$FORM{'pwd'}">
<SELECT NAME="kirikae">
<OPTION value="3" SELECTED>対フェイザー機能\を有効にする
<OPTION value="4">対フェイザー機能\を無効にする</SELECT>
<INPUT type="submit" value=" 実行 "></FORM><HR>
<H3>拒否ホスト登録モード</H3>
　※<A href="http://www.cup.com/yui/">YUI</A>さんのを改造</CENTER>
<BR><BR>
■完全なホスト名（例：nsi0123.ppp.3web.ne.jp）またはホスト名の一部（例：3web.ne.jp、dti.ne.jp、go.jp）いずれでも拒否登録できます。<BR>
<BR>
■ホスト名の一部を登録した場合、その名前を含むすべてのホストを拒否しますので注意して下さい。<BR>
（jpだけを登録した場合、jpドメインのすべてのホストを拒否してしまいます）<BR>
<BR>
■設置サーバーの種類よってはドメイン名ではキックできない場合がありますのでキックできない時はＩＰアドレス（例：202.235.202.57）で設定して下さい。<BR>
<BR>
<FORM method="POST" action="$reload">
<input type=hidden name="action" value="kickout">
<INPUT type="hidden" name="pwd" value="$FORM{'pwd'}">
ホスト名:<INPUT type="text" name="hostdate" size="30">
<SELECT NAME="touroku">
<OPTION value="1" SELECTED>新規に左記ホストを追加登録する
<OPTION value="2">ホスト登録ファイルを初期化する</SELECT>
<INPUT type="submit" value=" 実行 "></FORM><BR>
_HTML_

  if ($hostdate ne "" && $touroku eq '1') {
    if ( !open(DB,">>$hostlist") ) { &error('0'); }
    print DB "$hostdate\n";
    close(DB);
  }elsif ($touroku eq '2') {
    if ( !open(DB,">$hostlist") ) { &error('0'); }
    if ($pict) { 
      print DB "phaser_on\n";
    } else { 
      print DB "phaser_off\n";
    }
    close(DB);
  }
  if ( !open(DB,"$hostlist") ) { &error('0'); }
  @lines = <DB>;
  close(DB);
  print "<HR>下記が現在アクセス制限をかけているホストです。（１行目はフェイザーモード）";
  print "[<a href=\"$reload\">戻る</a>]<BR>";
    foreach $line (@lines) {
    print "$line<BR>";
  }
  print <<"_HTML_";
</BODY>
</HTML>
_HTML_
  exit;
}

#--- 漏れＩＰアドレス取得 --------------------------------#

sub getip {
  $sp_host   = $ENV{'HTTP_SP_HOST'};
  $client_ip = $ENV{'HTTP_CLIENT_IP'};
  $http_from = $ENV{'HTTP_FROM'};

  $trueip = $sp_host   if ($sp_host ne "");
  $trueip = $via       if ($via =~ s/.*\s(\d+)\.(\d+)\.(\d+)\.(\d+)/$1.$2.$3.$4/);
  if( $client_ip=~ s/^(\d+)\.(\d+)\.(\d+)\.(\d+)(\D*).*/$1.$2.$3.$4/ ){
    $trueip = $client_ip;
  }elsif( $client_ip=~ s/^([\dA-F]{2})([\dA-F]{2})([\dA-F]{2})([\dA-F]{2})/$1$2$3$4/i){
    $client_ip = join('.', hex($1), hex($2), hex($3), hex($4)); 
    $trueip = $client_ip;
  }
  $trueip = $for       if ($for =~ s/.*\s(\d+)\.(\d+)\.(\d+)\.(\d+)/$1.$2.$3.$4/);
  $trueip = $xfor      if ($xfor =~ s/^(\d+)\.(\d+)\.(\d+)\.(\d+)(\D*).*/$1.$2.$3.$4/);
  $trueip = $http_from if ($http_from ne "");
  return $trueip;
}

#--- アクセスログ用データ取得 --------------------------------#
sub acount {
  $date = $date_now;
  $href = $ENV{'HTTP_REFERER'};
  if ($href =~ /$reload/) {
    $href = "";
  } elsif ($href =~ /file:/) {
    $href = "";
  }
  $value_size = length($href);
  if ( $value_size > 120) { &error('x'); }
  $value_size = length($via);
  if ( $value_size > 120) { &error('x'); }
  $value_size = length($agent);
  if ( $value_size > 120) { &error('x'); }  
  if ( !open(LOG, "$access_log") ) { &error('0'); }
  @lines = <LOG>;
  close(LOG);
  $kiroku_data = "[$date ] $href - $host - $addr - $via - $trueip - $agent\n";
  unshift(@lines, "$kiroku_data");
  pop @lines while @lines > $rescue;
  if ( !open(LOG,">$access_log") ) { &error('0'); }
  print LOG @lines;
  close(LOG);
}

#--- カウンター --------------------------------#

sub count {
  if ( !open(DATA, "$counter") ) { &error('0'); }
  $c_number = <DATA>;
  close (DATA);
  $c_number ++;
  if ( !open(DATA,">>$counter") ) { &error('0'); }
  if ($use_flock == 1) {
    flock(DATA, 2);
  }
  truncate(DATA, 0);
  print DATA $c_number;
  close (DATA);
  return $c_number;
}

#--------- 固定ＩＤ登録モード ---------------------------#

sub id {

  $chcode = ($date_num + $num1) * $num2;
  # 投稿コードを任意のキーで暗号化
  $i = 0;
  $chcode =~ s/./sprintf("%02x",ord($&)^ord($key[$i++ % @key]))/ge;

if ($pict) { 
    $rport = $ENV{'REMOTE_PORT'};
    $himicode .= "?$ENV{'REMOTE_PORT'}";
  }

print <<"_HTML_";
Content-type: text/html

<html>
<head>
<title>$title</title>
$style
</head>
$body
<H4>固定ＩＤ登録モード</H4>
- 固定ＩＤを発行します -<br>
<INPUT type="hidden" fake="hogehoge" name="facheck1"
 value="$addr">
<form method="POST" action="$reload">
<input type="hidden" name="mode" value="idpost">
<!--
<INPUT type="hidden" fake="hogehoge" name="facheck1"
 value="$addr">
-->
<INPUT type="hidden" fake="hogehoge" name="facheck1"
 value="$chcode">
<!--
<INPUT type="hidden" fake="hogehoge" name="facheck1"
 value="$date_num">
-->
<INPUT type="hidden" fake="hogehoge" name="dammycode"
 value="$addr">
■ＩＤ設定<br>
<B>お名前</B>　<INPUT type="text" name="name" size="26" value="" > （半角で$max_n文字以内、全角はその半分まで）<br>
<B>登録ID</B>　<INPUT type="text" name="id" size="10" value="" maxlength="10" > （半角英数１０文字以内）<br>
<br>
■パスワード設定<br>
<B>パスワード</B>　<INPUT type="password" name="idpass1" size="8" value="" maxlength="8" > （半角英数８文字以内）<br>
<B>パスワード</B>　<INPUT type="password" name="idpass2" size="8" value="" maxlength="8" > （確認のため上と同じパスをもう一度）<P>
_HTML_

if ($pict) { # 対フェイザーがオンの場合の表示
    print "<TABLE bordercolor=\"#abd7fe\" cellspacing=\"0\" cellpadding=\"4\" bgcolor=\"\" border=\"1\"><TR><TD>\n";
    print "現在PHASER対策中です！　<INPUT type=\"text\" size=8 name=\"facheck2\"><BR>\n";
    print "画像数値を上の入力欄に書き写して投稿して下さい。</TD>\n";
    print "<TD><IMG SRC=\"$himicode\" ALIGN=TOP></TD></TR></TABLE><BR>\n";
    print "<INPUT type=\"hidden\" name=\"facheck3\" value=\"$rport\">\n";
  }
print <<"_HTML_";
<input type="submit" value="ＩＤ登録" > <input type="reset" value="リセット" >　　　　　　[ <a href="$reload">掲示板へ戻る</a> - <a href="$home">ホームへ</a> ]</form>
<HR width="98%" noshade size=1>
<H4>固定ＩＤ削除モード</H4>
- 固定ＩＤを削除します -<br>
<form method="POST" action="$reload">
■ＩＤ削除<br>
<input type="hidden" name="mode" value="delid">
<B>お名前</B>　<INPUT type="text" name="delname" size="26" value="" ><br>
<B>登録ID</B>　<INPUT type="text" name="delid" size="10" value="" ><br>
<br>
■登録時のパスワード<br>
<B>パスワード</B>　<INPUT type="password" name="delpas" size="8" value="" maxlength="8" ><p>
<input type="submit" value="ＩＤ削除" > <input type="reset" value="リセット" >　　　　　　[ <a href="$reload">掲示板へ戻る</a> - <a href="$home">ホームへ</a> ]
</form>
</body>
</html><hr>

_HTML_

exit;
}

#--------- 固定ＩＤ登録 ---------------------------#

sub idpost {

  if ($pcheck_flag != 1) { # 変数の取得　アクセス時にログを取っていなかった場合
    $via    = $ENV{'HTTP_VIA'};
    $xfor   = $ENV{'HTTP_X_FORWARDED_FOR'};
    $for    = $ENV{'HTTP_FORWARDED'};
    $agent  = $ENV{'HTTP_USER_AGENT'};
  }  
    $value_size = length($via);
    if ( $value_size > 150) { &error('x'); }
    $value_size = length($for);
    if ( $value_size > 150) { &error('x'); }
    $value_size = length($agent);
    if ( $value_size > 150) { &error('x'); }  

  if ( ($kyoka eq "") && ($proxy == 1) ) {
    &proxy;
  } elsif ( ($host !~ /$kyoka/) && ($proxy == 1) ) {
    &proxy;
  }

  &code_check;

  if (($FORM{'name'} eq "") || ($FORM{'name'} eq " ") || ($FORM{'name'} eq "　")) { 
    &errorz('お名前がないっ（^^；',"お名前を書いて下さい。");
  }
  if (($FORM{'id'} eq "") || ($FORM{'id'} eq " ") || ($FORM{'id'} eq "　")) { 
    &errorz('ＩＤがないっ（^^；',"ＩＤを書いて下さい。");
  }
  if (($FORM{'id'} =~ /\W/) || (length($FORM{'id'}) > 10)) {
    &errorz('入力ミス','ＩＤは半角英数１０文字以内で記入してください');
  }
  if (($FORM{'idpass1'} eq "") || ($FORM{'idpass1'} =~ /\W/) || (length($FORM{'idpass1'}) > 8)) {
    &errorz('パスワード入力ミス',"パスワードは半角英数８文字以内で記入してください");
  }
  if (($FORM{'idpass2'} eq "") || ($FORM{'idpass2'} =~ /\W/) || (length($FORM{'idpass2'}) > 8)) {
    &errorz('パスワード（確認用）入力ミス',"パスワードは半角英数８文字以内で記入してください");
  }
  if (($FORM{'idpass1'} ne $FORM{'idpass2'})) {
    &errorz('入力ミス',"パスワードが確認用パスワードと一致しません");
  }
  if ($max_n) {
    $value_size = length($FORM{'name'});
    if ($value_size > $max_n) {
      &errorz('お名前が長すぎっ（^^；',"お名前が最大記録サイズ$max_nを超えています。現在$value_sizeサイズです。");
    }
  }

# ここでダブリと管理者名＆管理者ＩＤ登録の拒否と追加をする。

if (($FORM{'name'} =~ /\W/) || ($master =~ /\W/)) {
  if ($FORM{'name'} eq "$master") {
    &errorz('入力ミス','お名前が管理人と同一です');
  }
}
elsif ($FORM{'name'} =~ /^$master$/i) {
  &errorz('入力ミス','お名前が管理人と同一です（大文字・小文字の違いは無視）');
}  

if ($master_id =~ /\W/) {
  if ($FORM{'id'} eq $master_id) {
    &errorz('入力ミス','ＩＤが管理人と同一です');
  }
}
elsif ($FORM{'id'} =~ /^$master_id$/i) {
  &errorz('入力ミス','ＩＤが管理人と同一です（大文字・小文字の違いは無視）');
}
elsif ($FORM{'id'} =~ /$denyID/i) {
  &errorz('入力ミス','登録できないＩＤです（大文字・小文字の違いは無視）');
}

$i = 0;
@idlog = ();
open(ID,"$idlist") || die "Can't Open ID List: $!\n";
while (<ID>) {
 ($number, $id, $date0, $idpass0, $name, $host0, $addr0, $via0, $for0, $trueip0, $agent0, $checkcode) = split(/\,/,);
  $i++;
  if ($FORM{'id'} =~ /^$id$/i) {
    close(ID);
    &errorz('取得済みＩＤ',"そのＩＤは既に取得されています（大文字･小文字の違いは無視）");
  }
  if (($FORM{'name'} =~/\W/) || ($name =~ /\W/)) {
    if ($FORM{'name'} eq $name) {
      close(ID);
      &errorz('お名前が取得済み','そのお名前は既に取得されています');
    }
  }
  elsif ($FORM{'name'} =~ /^$name$/i) {
    close(ID);
    &errorz('お名前が取得済み',"そのお名前は既に取得されています（大文字･小文字の違いは無視）");
  }
  if (($i < $dc) && ($p_check)) { 
    if ($ctimer == 0) {
        if (($host eq $host0) && ($date_num > $number) && ($date_num - $number < $timer) ) {
          close(ID);
          &errorz('少しお待ち下さい（^^；',"悪戯対策のため同一ホストからの$rtimer分以内の連続投稿はできなくなっています。");
        }
      }
      if ($ctimer == 1) {
        if (($date_num > $number) && ($date_num - $number < $timer) ) {
          close(ID);
          &errorz('少しお待ち下さい（^^；',"悪戯対策のため直前の投稿から$rtimer分以内の連続投稿はできなくなっています。");
        }
      }
  }
push(@idlog, "$_");
}
close(ID);

if ($max_id) {
  if (@idlog >= $max_id) {
    &errorz('ＩＤ登録数オーバー',"ＩＤ最大登録数$max_idを超えています<BR>管理者にＩＤ登録件数を増やすよう伝えてください");
  }
}

$agent =~ s/,/./g;
$via =~ s/,/./g;
$for =~ s/,/./g;
$trueip =~ s/,/./g;

$idpass = crypt($FORM{'idpass1'}, &mkSalt($FORM{'name'}.$FORM{'idpass1'}.$idps) );
$newid = "$date_num\,$FORM{'id'}\,$date_now\,$idpass\,$FORM{'name'}\,$host\,$addr\,$via\,$for\,$trueip\,$agent\,$dukecheck";

#ＩＤを登録する
  unshift(@idlog, "$newid\n");
  open(IDLOG,">>$idlist") || die "Can't Open ID List: $!\n";
  if ($use_flock == 1) {
    flock(IDLOG, 2);
  }
  truncate(IDLOG, 0);
  print IDLOG @idlog;
  close(IDLOG);

print <<"_HTML_";
Content-type: text/html

<html>
<head>
<title>$title</title>
$style
</head>
$body
<H4>ＩＤが設定されました</H4>
お名前： $FORM{'name'} 　　ＩＤ： $FORM{'id'}<BR><BR>
ＩＤ設定時のお名前とパスワードを使用することで登録したＩＤが表\示されます。<BR><BR>

[ <a href="$reload">掲示板へ戻る</a> - <a href="$home">ホームへ</a> ]
</body>
</html>
_HTML_

exit;
}

#---------------- 固定ＩＤ削除（ゲスト） ----------------------#

sub del_id {
if ($FORM{'delname'} eq "") { &errorz('入力ミス','お名前が入力されていません'); }
elsif ($max_n) {
  if (length($FORM{'delname'}) > $max_n) { &errorz('入力ミス','お名前は半角で$max_n文字、全角はその半分までです'); }
}
elsif ($FORM{'delid'} eq "") { &errorz('入力ミス','ＩＤが入力されていません'); }
elsif ((length($FORM{'delid'}) > 10) && ($FORM{'delid'} =~ /\W/)) {  &errorz('入力ミス','ＩＤは半角英数字で１０文字以内です'); }
elsif ($FORM{'delpas'} eq "") { &errorz('入力ミス','パスワードが入力されていません'); }
elsif ((length($FORM{'delpas'}) > 8) && ($FORM{'delpas'} =~ /\W/)) { &errorz('入力ミス','パスワードは半角英数字で８文字以内です'); }

@newid = ();
$flag = 0;
$delpwd = crypt($FORM{'delpas'}, &mkSalt($FORM{'delname'}.$FORM{'delpas'}.$idps) );

open(ID,"$idlist") || die "Can't Open ID List: $!\n";
   while (<ID>) {
      ($number0, $id, $date0, $idpass0, $name0, $host0, $addr0, $via0, $for0, $trueip0, $agent0, $checkcode) = split(/\,/,);

    if ($flag != 1) {
      if (($FORM{'delname'} =~ /\W/) || ($name0 =~ /\W/)) {
        if (($FORM{'delname'} eq $name0) && ($FORM{'delid'} eq $id) && ($delpwd eq $idpass0)) {
          $_ = "";
          $flag = 1;
        }
      }
      elsif (($FORM{'delname'} =~ /^$name0$/i) && ($FORM{'delid'} eq $id) && ($delpwd eq $idpass0)) {
        $_ = "";
        $flag = 1;
      }
    }
   push(@newid, $_);
   }
 close(ID);

if ($flag == 1) {
  open(IDLOG,">>$idlist") || die "Can't Open ID List: $!\n";
  if ($use_flock == 1) {
    flock(IDLOG, 2);
  }
  truncate(IDLOG, 0);
  print IDLOG @newid;
  close(IDLOG);

print <<"_HTML_";
Content-type: text/html

<html>
<head>
<title>$title</title>
$style
</head>
$body
<H4>ＩＤを削除しました</H4>
お名前: $FORM{'delname'}　　ＩＤ： $FORM{'delid'}　は削除されました。<br>
<br>
[ <a href="$reload">掲示板へ戻る</a> - <a href="$home">ホームへ</a> ]
</body>
</html>
_HTML_
}
else { &errorz('削除対象が見つかりません','お名前、ＩＤ、パスワードをもう一度確認して入力してください'); }

exit;
}

#---------------- 固定ＩＤ一覧（管理者） ----------------------#

sub remid1 {

  print <<"_HTML_";
Content-type: text/html

<HTML>
<HEAD>
<TITLE>$title</TITLE>
$style
</HEAD>
$body
<FONT size="+1"><B>ＩＤ一覧モード（ＩＤ削除もできます）</B></FONT>  [<A href="$reload">戻る</A>]<P>
<FORM method="POST" action="$reload">
<input type=hidden name="action" value="remid2">
<PRE>
     登録日               ハンドル名     認識ＩＤ          アクセスデータ(REMOTE_HOST - REMOTE_ADDR - HTTP_VIA - HTTP_FORWARDED - TrueIP - USER_AGENT)<hr>
_HTML_
 open(ID,"$idlist") || die "Can't Open ID List: $!\n";
   while (<ID>) {
   ($number, $id, $date, $idpass, $name, $host, $addr, $via, $for, $trueip, $agent, $checkcode) = split(/\,/,);
    $name =~ s/\0/\,/g;
    $name  =~ s/</&lt;/ig;
    $name  =~ s/>/&gt;/ig;
    $via  =~ s/</&lt;/ig;
    $via  =~ s/>/&gt;/ig;
    $for  =~ s/</&lt;/ig;
    $for  =~ s/>/&gt;/ig;
    $trueip  =~ s/</&lt;/ig;
    $trueip  =~ s/>/&gt;/ig;
    $agent  =~ s/</&lt;/ig;
    $agent  =~ s/>/&gt;/ig;
        
    $i1 = length($name);
    if ($i1 > 14) {
      $name = substr($name, 0, 14);
    } elsif ($i1 < 14) {
      $blank = ' ' x (14 - $i1);
      $name = $name . $blank;
    }
    
    $id =~ s/^.*(.{11})$/$1/;
    $i3 = length($id);
    $blank = '-' x (13 - $i3);
    print "<INPUT type=\"checkbox\" name=\"del\" value=\"$number:$id\">";
    $id = $id . $blank;
    print " $date - $name($id) - $host - $addr - $via - $for - $trueip - $agent\n";
    }
  close(ID);
  
print <<"_HTML_";
</PRE><P>
<INPUT type="hidden" name="pwd" value="$FORM{'pwd'}">
<INPUT type="submit" value="     削除     "><INPUT type="reset" value="リセット">
</FORM><P>
</BODY>
</HTML>
_HTML_

exit;
}

#---------------- 固定ＩＤ削除（管理者）-----------------#

sub remid2 {
@newid = ();
$flag = 0;
($del_num, $del_id) = split(/:/, $FORM{'del'});

open(ID,"$idlist") || die "Can't Open ID List: $!\n";
   while (<ID>) {
      ($number0, $id, $date0, $idpass0, $name0, $host0, $addr0, $via0, $for0, $trueip0, $agent0, $checkcode) = split(/\,/,);

    if ($flag != 1) {
      if (($del_num == $number0) && ($del_id == $id)) {
        $_ = "";
        $flag = 1;
      }
    }
   push(@newid, $_);
   }
 close(ID);

if ($flag == 1) {
  open(IDLOG,">>$idlist") || die "Can't Open ID List: $!\n";
  if ($use_flock == 1) {
    flock(IDLOG, 2);
  }
  truncate(IDLOG, 0);
  print IDLOG @newid;
  close(IDLOG);
}

}

#--- 定型エラー処理 --------------------------------#

sub error {
  $error = $_[0];
  if ($error eq "0") {
    $error_msg = '記録ファイルの入出力にエラーが発生しました。<BR><BR>設置ファイルの名称、パーミッションを再確認して下さい。';
  } elsif ($error eq "kusi") {
    $error_msg = '<FONT SIZE="+2">現在プロクシ制限中です！</FONT><BR><BR>プロクシ経由は許可されていません。<BR>掲示板管理者にメール等で該当ホストの許可設定を申\し出て下さい。';
  } elsif ($error eq "x") {
    $error_msg = 'チェックコードの入力間違い？、または不正利用です(^^;;';
  }

print <<"_HTML_";
Content-type: text/html

<HTML>
<HEAD><TITLE>$title</TITLE></HEAD>
$body
<H3>$error_msg</H3>
ブラウザの[戻る]ボタンを押して前の画面に移動して下さい。<P>
_HTML_
  if($FORM{'value'} ne ''){
    $FORM{'value'} =~ s/<br>//g; 
    print "[下記は投稿内容のバックアップ]<FORM><TEXTAREA NAME=\"repost\" ROWS=20 COLS=80>\n";
    print "$FORM{'value'}\n";
    print "</TEXTAREA></FORM>\n";
  }
  print <<"_HTML_";
</BODY>
</HTML>
_HTML_
  exit;
}

#--- 個別エラー処理 --------------------------------#

sub errorz {
  print <<"_HTML_";
Content-type: text/html

<HTML>
<HEAD><TITLE>$title</TITLE></HEAD>
$body
<H1>$_[0]</H1>
<H3>$_[1]</H3>
ブラウザの[戻る]ボタンを押して前の画面に移動して下さい。<P>
_HTML_
  if($FORM{'value'} ne ''){
    $FORM{'value'} =~ s/<br>//g; 
    print "[下記は投稿内容のバックアップ]<FORM><TEXTAREA NAME=\"repost\" ROWS=20 COLS=80>\n";
    print "$FORM{'value'}\n";
    print "</TEXTAREA></FORM>\n";
  }
  print <<"_HTML_";
</BODY>
</HTML>
_HTML_
  exit;
}