#!/usr/local/bin/perl
#こちらの変更点は簡単にします。やる事と言えば管理するあなた用のパスワード設定ぐらいです。(exlion)
## Web Forum for Admin v2.6 (00/05/20)
## Copyright(C) Kent Web 2000
## webmaster@kent-web.com
## http://www.kent-web.com/

$ver = 'WF ADMIN v2.6';

#============#
# 設定項目 #
#============#

# 文字コードライブラリ
require './jcode.pl';

# パスワード (半角英数字で)
$pass = 'こにあなたの管理者パスワードを入力してください';

# スクリプト名
$script = './wf_admin.cgi';

# ログファイル
$logfile = './wforum.log';

# 掲示板のファイル
$bbsurl = './wforum.cgi';

# タグ処理 (0=no 1=yes)
$tagkey = 0;

# ロックファイル (wforum.cgiの設定に合わせること)
$lockfile = './wforum.lock';

# ロックファイルの使用
#(0=no 1=symlink関数 2=open関数)(NTサ-バーは「2」に設定した方が良いそうです
$lockkey = 2;

# methodの形式 (POST/GET)
$method = 'POST';

# bodyタグ
$body = '<BODY BGCOLOR="#F1F1F1" TEXT="#000000" link="#0000E3" vlink="#008080">';

#============#
# 設定完了 #
#============#

&decode;
if ($mode eq "log_view") { &log_view; }
if ($mode eq "edit1") { &edit1; }
if ($mode eq "edit2") { &edit2; }
if ($mode eq "delete") { &delete; }
&enter;

#----------------#
# ログ閲覧画面 #
#----------------#
sub log_view {
if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); }

# ログを開く
open(IN,"$logfile") || &error("Open Error : $logfile");
@lines = <IN>;
close(IN);

# 記事NOをカット
shift(@lines);

&header;
print <<"EOM";
<center><table border=0 cellpadding=10>
<tr><td nowrap>
<small>
<OL>
<LI>記事を<B>削除</B>する場合、削除する記事の<B>チェックボックス</B>にチェックを付けて削除キーを押してください。
<LI>記事を<B>編集</B>する場合には「題名」のリンク部をクリックしてください。
</OL>
</small>
</td></tr></table>
</center>
<blockquote>
<form action="$script" method=$method>
<input type=hidden name=mode value="delete">
<input type=hidden name=pass value="$in{'pass'}">
EOM

print "<input type=submit value=\"削除する\"><input type=reset value=\"リセット\">\n";

$x = 0;
print "<DL>\n";
foreach $line (@lines) {
($no,$reno,$lx,$sub,$email,$url,$name,
$date,$msg,$time,$host,$pw,$wrap,$oya) = split(/<>/,$line);

while ($x > $lx) { print "</DL>"; $x--; }
while ($x < $lx) { print "<DL>"; $x++; }

if ($no eq "$oya") {
$sub = "<B>$sub</B>";
print "<hr size=1>\n";
print "<DT><input type=checkbox name=treedel value=\"$no\">\n";
print "<font color=#dd0000 size=2>[ツリーの一括削除]</font>\n";
}

print "<DT><input type=checkbox name=del value=\"$no\"> ";
print "<a href=$script?mode=edit1&no=$no&pass=$in{'pass'}>$sub</a>\n";
print "<small> - <B>$name</B> $date ($host) <font color=#800000>No\.$no</font></small>\n";

while ($x > 0) { print "</DL>"; $x--; }

}

print "</DL>\n";
print "</form>\n</blockquote>\n<hr>\n";

# 著作権表示(削除禁止)
print "<center><small><!-- $ver -->\n";
print "- <a href=\"http://www.kent-web.com/\" target='_top'>WF Admin</a> -\n";
print "</small></center>\n";
print "</body></html>\n";
exit;
}

#----------------#
# 記事編集画面 #
#----------------#
sub edit1 {
if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); }

# ログを開く
open(IN,"$logfile") || &error("Can't open $logfile");
@lines = <IN>;
close(IN);
shift(@lines);

$flag=0;
foreach $line (@lines) {
($no,$reno,$x,$sub,$email,$url,$name,
$date,$msg,$time,$host,$pw,$wrap,$oya) = split(/<>/,$line);

if ($in{'no'} eq "$no") { $flag=1; last; }
}

if ($flag == 0) { &error("編集対象記事が見当たりません"); }

$msg =~ s/<br>/\r/g;

&get_agent;

# 編集フォームを出力
&header;
print <<"EOM";
<center><table border=0 cellpadding=10>
<tr><td bgcolor=#FFFFFF>
■変更したい部分のみ修正し、送信キーを押してください<br>
</td></tr>
</table><P>
<form action="$script" method=$method>
<input type=hidden name=mode value="edit2">
<input type=hidden name=action value="edit">
<input type=hidden name=no value="$in{'no'}">
<input type=hidden name=pass value="$in{'pass'}">
<table border=0>
<tr>
<td><B>投稿者</B></td>
<td><input type=text name=name value="$name" size=$nam_wid></td>
</tr>
<tr>
<td><B>Eメール</B></td>
<td><input type=text name=email value="$email" size=$nam_wid></td>
</tr>
<tr>
<td><B>タイトル</B></td>
<td><input type=text name=sub value="$sub" size=$subj_wid>
<input type=submit value="送信する"><input type=reset value="リセット"></td>
</tr>
<tr>
<td colspan=2><B>コメント</B><br>
<textarea name=msg cols=$com_wid rows=18 wrap=soft>$msg</textarea></td>
</tr>
<tr>
<td><B>URL</B></td>
<td><input type=text name=url value="http://$url" size=$url_wid></td>
</tr>
</table>
</form></center>
</body></html>
EOM
exit;
}

#----------------#
# 記事編集処理 #
#----------------#
sub edit2 {
if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); }

# ログを開く
open(IN,"$logfile") || &error("Open Error : $logfile");
@lines = <IN>;
close(IN);

$top = shift(@lines);

$in{'url'} =~ s/^http\:\/\///;

$flag=0;
@new=();
foreach $line (@lines) {
($no,$reno,$x,$sub,$email,$url,$name,
$date,$msg,$time,$host,$pw,$wrap,$oya) = split(/<>/,$line);

if ($in{'no'} eq "$no") {
$flag=1;
$line = "$no<>$reno<>$x<>$in{'sub'}<>$in{'email'}<>$in{'url'}<>$in{'name'}<>$date<>$in{'msg'}<>$time<>$host<>$pw<>$wrap<>$oya<>\n";
}
push(@new,$line);
}

if ($flag == 0) { &error("編集対象記事が見当たりません"); }

unshift(@new,$top);

# ログを更新
open(OUT,">$logfile") || &error("Write Error : $logfile");
print OUT @new;
close(OUT);

# 初期画面に戻る
&log_view;
}

#----------------#
# 記事削除処理 #
#----------------#
sub delete {
if ($DEL[0] eq "" && $TDEL[0] eq "") { &error("削除情報がありません"); }
if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); }

# ログを開く
open(IN,"$logfile") || &error("Open Error : $logfile");
@lines = <IN>;
close(IN);

# 記事No情報を一時カット
$head = shift(@lines);

$key1=0; $key2=0;

@temp=();
if ($TDEL[0]) {
$key1=1; # ツリー削除あり
foreach $line (@lines) {
$tflag=0;
($no,$reno,$x,$sub,$email,$url,$name,
$date,$msg,$time,$host,$pw,$wrap,$oya) = split(/<>/,$line);

foreach $tdel (@TDEL) {
if ($oya eq "$tdel") { $tflag=1; last; }
}
if ($tflag == 0) { push(@temp,$line); }
}

@lines = @temp;
}


# 削除情報とログをマッチし、@new に格納
if ($DEL[0]) {
$key2=1; # 個別削除あり
@new=();
foreach $line (@lines) {
$flag = 0;
$oflag = 0;
($no,$reno,$x,$sub,$email,$url,$name,
$date,$msg,$time,$host,$pw,$wrap,$oya) = split(/<>/,$line);

if ($no eq "$oya") { $oflag=1; }

foreach $del (@DEL) {
if ($oflag == 0 && $no eq "$del") { $flag=1; last; }
if ($oflag == 1 && $no eq "$del") {
$line = "$no<>$reno<>$lx<>(削除)<><><>(削除)<>$date<>(削除されました)<>$time<>$host<><><>$oya<>\n";
last;
}
}

if ($flag == 0) { push(@new,$line); }
}
}

# 配列を定義
if ($key1 == 1 && $key2 == 0) { @data = @lines; }
else { @data = @new; }

# 記事Noを付加
unshift(@data,$head);

# ログを更新
open(OUT,">$logfile") || &error("Write Error : $logfile");
print OUT @data;
close(OUT);

# 初期画面に戻る
&log_view;
}

#------------#
# 入室画面 #
#------------#
sub enter {
&header;
print "<center><h4>パスワードを入力してください</h4>\n";
print "<form action=\"$script\" method=$method>\n";
print "<input type=hidden name=mode value=\"log_view\">\n";
print "<input type=password name=pass size=8>";
print "<input type=submit value=\"認証\">\n";
print "</form></center>\n";
print "</body></html>\n";
exit;
}

#--------------#
# HTMLヘッダ #
#--------------#
sub header {
print "Content-type: text/html\n\n";
print <<"EOM";
<html>
<head>
<STYLE type="text/css">
<!--
body,tr,td,th { font-size: 10pt }
small { font-size: 9pt }
-->
</STYLE>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=Shift_JIS">
<title>Web Forum for Admin</title></head>
$body
[<a href="$bbsurl" target="_top">戻る</a>]
<table width="100%"><tr><th bgcolor="#8080C0">
<font color="#FFFFFF">管 理 モ ー ド</font>
</th></tr></table>
<P>
EOM
}

#--------------------#
# フォームデコード #
#--------------------#
sub decode {
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", "", "z");

# タグ処理
if ($tagkey == 0) {
$value =~ s/</&lt;/g;
$value =~ s/>/&gt;/g;
$value =~ s/\"/&quot;/g;
} else {
$value =~ s/<>/&lt;&gt;/g;
}

# 改行処理
if ($name eq "msg") {
$value =~ s/\r\n/<br>/g;
$value =~ s/\r/<br>/g;
$value =~ s/\n/<br>/g;
} else {
$value =~ s/\r//g;
$value =~ s/\n//g;
}

# 削除データをプール
if ($name eq "del") { push(@DEL,$value); }
elsif ($name eq "treedel") { push(@TDEL,$value); }

$in{$name} = $value;
}
$mode = $in{'mode'};
}

#--------------#
# エラー処理 #
#--------------#
sub error {
if (-e $lockfile) { unlink($lockfile); }

&header;
print "<center><hr width='75%'><h3>ERROR !</h3>\n";
print "<P><font color=#DD0000><B>$_[0]</B></font>\n";
print "<P><hr width='75%'></center>\n";
print "</body></html>\n";
exit;
}

#--------------------#
# フォーム長を調整 #
#--------------------#
sub get_agent {
$agent = $ENV{'HTTP_USER_AGENT'};

if ($agent =~ /MSIE 3/i) {
$nam_wid = 30;
$subj_wid = 40;
$com_wid = 64;
$url_wid = 46;
}
elsif ($agent =~ /MSIE 4/i || $agent =~ /MSIE 5/i) {
$nam_wid = 30;
$subj_wid = 40;
$com_wid = 64;
$url_wid = 78;
}
else {
$nam_wid = 20;
$subj_wid = 27;
$com_wid = 62;
$url_wid = 52;
}
}

#--------------------------------#
# ロックファイル : symlink関数 #
#--------------------------------#
sub lock1 {
local($retry) = 5;
while (!symlink(".", $lockfile)) {
if (--$retry <= 0) { &error("LOCK is BUSY"); }
sleep(1);
}
}

#-----------------------------#
# ロックファイル : open関数 #
#-----------------------------#
sub lock2 {
local($flag) = 0;
foreach (1 .. 5) {
if (-e $lockfile) { sleep(1); }
else {
$flag = 1;
open(LOCK,">$lockfile");
close(LOCK);
last;
}
}
if ($flag == 0) { &error("LOCK is BUSY"); }
}


Return