#!/usr/bin/perl
## ----------------------------------------------------------------------------+
## YY-BOARD v2.63 (1999/08/16)
## (C) 1998-99 by KENT WEB
## E-MAIL: webmaster@kent-web.com
## WWW: http://www.kent-web.com/
$ver = 'YYBBS v2.63'; # バージョン情報(修正不要)
## ---[注意事項]---------------------------------------------------------------+
## 1. このスクリプトはフリーソフトです。このスクリプトを使用したいかなる損害に
## 対して作者は一切の責任を負いません。
## 2. 設置に関する質問はサポート掲示板にお願いいたします。メールによる質問には
## お答えできません。
## 3. 同梱の「家アイコン (home.gif) 」は、「牛飼いとアイコンの部屋
## (http://www.ushikai.com/)」によるもので、作者の合意の元に再配布するものです。
## ----------------------------------------------------------------------------+
## --- 基本設定
# jcode.plが同一ディレクトリにある場合
require './jcode.pl';
# タイトル名を指定
$title = "花の都の掲示板";
# タイトルの色
$t_color = "#FF0000";
# タイトル文字の大きさ(font size)
$t_size = 13;
# タイトル文字のフォントタイプ
$t_face = "麗流隷書";
# 壁紙を仕様する場合(http://から指定)
$backgif = "http://www1.ocn.ne.jp/~chu/sakura/yagasuri02.gif";
# 背景色を指定
$bgcolor = "#FFB6CI";
# 文字色を指定
$text = "#191970";
# リンク色を指定
$link = "#0000FF"; # 未訪問
$vlink = "#00BFFF"; # 訪問済
$alink = "#00FFFF"; # 訪問中
# 戻り先のURL (index.htmlなど)
$homepage = "http://www1.ocn.ne.jp/~chu/";
# 親記事最大記事数 (あまり多くすると危険)
# --> レス記事の数は最大記事数には含まれません
$max = 70;
# 管理者用マスタパスワード (英数字で8文字以内)
$pass = 'masamasa';
# アイコン画像のある「ディレクトリ」
# --> yybbs.cgi と別ディレクトリとなる場合は、http://から記述する。
$icon_dir = ".";
# アイコンを定義(上下は必ずペアで)
@icon1 = ('sakura.GIF','sumire.GIF','maria.GIF','iris.GIF','kouran.GIF','kanna.GIF',
'orihime.GIF','reni.GIF','oogami.GIF','kayama.GIF','kaede.GIF','kasumi.GIF','yuri.GIF','tsubaki.GIF',
'kotone.GIF','kiku.GIF','yokihiko.GIF','saki.GIF','oniou.GIF','kongou.GIF','kasya.GIF','mokujiki.GIF','tsuchigumo.GIF');
@icon2 = ('さくら','すみれ','マリア','アイリス','紅蘭','カンナ',
'織姫','レニ','大神','加山','かえで','かすみ','由里','椿',
'琴音','菊乃丞','斧彦','サキ','鬼王','金剛','火車','木喰','土蜘蛛');
# 管理者専用アイコン機能 (0=no 1=yes)
# --> 【使い方】記事投稿時に「管理者アイコン」を選択し、削除キーに
# 「管理用パスワード」を入力して下さい。
$my_icon = 0;
# 管理者専用アイコンの「ファイル名」を指定
$my_gif = 'admin.gif';
## --- 応用設定(ここからは場合に応じての設定内容)
# アイコンモード (0=no 1=yes)
$icon_mode = 1;
# 返信がつくと親記事をトップへ移動 (0=no 1=yes)
$res_sort = 0;
# ホスト名取得モード
# --> 0 : $ENV{'REMOTE_HOST'} で取得できる場合
# --> 1 : gethostbyaddr で取得できる場合
$get_remotehost = 1;
# タイトルにGIF画像を使用する時 (http://から記述)
$title_gif = "http://www1.ocn.ne.jp/~chu/sakura/hana_rogo.gif";
$tg_w = '550'; # GIF画像の幅 (ピクセル)
$tg_h = '100'; # 〃 高さ (ピクセル)
# ファイルロック形式
# --> 0=no 1=symlink関数 2=open関数
# --> 1 or 2 を設定する場合は、ロックファイルを生成するディレクトリ
# のパーミッションは 777 に設定する。
$lockkey = 1;
$lockfile = "yybbs.lock"; # ロックファイル名
$lock_dir = "."; # ロックファイルのディレクトリ
# ミニカウンタの設置
# --> 0=no 1=テキスト 2=GIF画像
$counter = 0;
$mini_fig = 5; # ミニカウンタの桁数
$cnt_color = "#dd0000"; # テキストのとき:ミニカウンタの色
$gif_path = "."; # GIFのとき :画像までのディレクトリ
$mini_w = 8; # 〃 :画像の横サイズ
$mini_h = 12; # 〃 :画像の縦サイズ
$cntfile = "./count.dat"; # カウンタファイル
# タグの許可 (0=no 1=yes)
$tagkey = 0;
# スクリプトのファイル名
$script = "http://www3.tok2.com/home/chuchu/cgi-bin/yybbs.cgi";
# ログファイルを指定
# --> フルパスで指定する場合は / から始まるフルパスで。
$logfile = "./yybbs.log";
# 記事の [タイトル] 部の色
$sbj_color = "#006400";
# 記事表示部の下地の色
$tbl_color = "#FFFFFF";
# 家アイコンの使用 (0=no 1=yes)
$home_icon = 1;
$home_gif = "home.gif"; # 家アイコンのファイル名
$home_wid = 25; # 画像の横サイズ
$home_hei = 22; # 〃 縦サイズ
# methodの形式 (POST/GET)
$method = 'POST';
# 1ページ当たりの記事表示数 (親記事)
$pagelog = 10;
# 投稿があるとメール通知する (0=no 1=yes)
# --> sendmail必須
$mailing = 0;
$mailto = 'user@host.ne.jp'; # メールアドレス(メール通知する時)
$sendmail = '/usr/lib/sendmail'; # sendmailパス(メール通知する時)
$mail_me = 0; # 自分の投稿記事はメール通知する (0=no 1=yes)
# 他サイトから投稿排除時に指定 (http://から書く)
$base_url = ".";
# 文字色の設定。
@COLORS = ('800000','DF0000','008040','0000FF','C100C1','FF80C0','FF8040','000080');
# 投稿フォーム改行形式 (soft=手動 hard=強制)
$wrap = 'soft';
# URLの自動リンク (0=no 1=yes)
# --> タグ許可の場合は no とすること。
$autolink = 1;
# 過去ログ生成 (0=no 1=yes)
$pastkey = 0;
$nofile = "./pastno.dat"; # 過去ログ用NOファイル
$past_dir = "."; # 過去ログのディレクトリ
$log_line = '150'; # 過去ログ1ファイルの行数
$yybbs2 = "./yybbs2.cgi"; # 過去ログ管理ファイル
## --- 設定ここまで
## ロックファイルを定義
$lockfile = "$lock_dir\/$lockfile";
## --- メイン処理
&form_decode;
if ($mode eq "howto") { &howto; }
if ($mode eq "find") { &find; }
if ($mode eq "usr_del") { &usr_del; }
if ($mode eq "msg_del") { &msg_del; }
if ($mode eq "msg") { ®ist; }
if ($mode eq "res_msg") { &res_msg; }
if ($mode eq "admin") { &admin; }
if ($mode eq "admin_del") { &admin_del; }
if ($mode eq "image") { ℑ }
&html_log;
## --- 記事表示部
sub html_log {
# クッキーを取得
&get_cookie;
# フォーム長を調整
&get_agent;
# ログを読み込み
open(IN,"$logfile") || &error("Can't open $logfile",'NOLOCK');
@lines = ;
close(IN);
# 記事番号をカット
shift(@lines);
# 親記事のみの配列データを作成
@new = ();
foreach $line (@lines) {
local($num,$k,$dt,$na,$em,$sub,$com,
$url,$host,$pw,$color,$icon) = split(/<>/, $line);
# 親記事を集約
if ($k eq "") { push(@new,$line); }
}
# レス記事はレス順につけるため配列を逆順にする
@lines = reverse(@lines);
# ヘッダを出力
&header;
# カウンタ処理
if ($counter) { &counter; }
# タイトル部
if ($title_gif eq '') {
print "";
print "$title\n";
} else {
print "\n";
}
print "
\n";
print "[トップにもどる]\n";
print "[掲示板の使い方]\n";
print "[ワード検索]\n";
# 過去ログのリンク部を表示
if ($pastkey) {
print "[過去ログ]\n";
}
print <<"EOM";
[記事削除]
[管理用]
\n";
if ($FORM{'page'} eq '') { $page = 0; }
else { $page = $FORM{'page'}; }
# 記事数を取得
$end_data = @new - 1;
$page_end = $page + ($pagelog - 1);
if ($page_end >= $end_data) { $page_end = $end_data; }
foreach ($page .. $page_end) {
($number,$k,$date,$name,$email,$sbj,
$comment,$url,$host,$pwd,$color,$icon) = split(/<>/, $new[$_]);
if ($email) { $name = "$name"; }
if (!$sbj) { $sbj = "Untitled"; }
# URL表示
if ($url && $home_icon) {
$url = "";
} elsif ($url && $home_icon == 0) {
$url = "[HOME]";
}
print "\n";
print "\n";
print "\n";
$icon =~ s/\n//g;
if ($icon ne "") { print " | \n"; }
else { print " | \n"; }
# 自動リンク
if ($autolink) { &auto_link($comment); }
print "$comment | \n";
## レスメッセージを表示
$flag = 0;
foreach $line (@lines) {
($rnum,$rk,$rd,$rname,$rem,$rsub,
$rcom,$rurl,$rho,$rp,$rc,$ri) = split(/<>/,$line);
if ($rem) { $rname = "$rname"; }
if ($number eq "$rk"){
if ($flag == 0) { print " \n"; $flag=1; }
print " | \n";
$ri =~ s/\n//g;
if ($ri ne "") {
print " | \n";
} else {
print " | \n";
}
if ($rsub eq "") { $rsub = "Untitled"; }
print "";
print "$rsub \n";
print "投稿者:$rname - \n";
print "$rd | \n";
# URL表示
if ($rurl && $home_icon) {
print " | \n";
}
elsif ($rurl && $home_icon == 0) {
print "[HOME] | \n";
}
# 自動リンク
if ($autolink) { &auto_link($rcom); }
print " \n";
print "$rcom | \n";
}
}
print " |
\n";
}
print "
\n";
&footer;
exit;
}
## --- ログ書き込み処理
sub regist {
# 他サイトからのアクセスを排除
if ($base_url ne ".") {
$ref_url = $ENV{'HTTP_REFERER'};
$ref_url =~ s/\?(.|\n)*//ig;
$ref_url =~ s/\%7E/\~/ig;
if ($ref_url && $ref_url !~ $base_url) {
&error("不正なアクセスです。",'NOLOCK');
}
}
# 名前とコメントは必須
if ($name eq "") { &error("名前が入力されていません。",'NOLOCK'); }
if ($comment eq "") { &error("コメントが入力されていません。",'NOLOCK'); }
if ($email && $email !~ /(.*)\@(.*)\.(.*)/) {
&error("Eメールの入力内容が正しくありません。",'NOLOCK');
}
# 管理アイコンのチェック
if ($my_icon && $icon eq "$my_gif") {
if ($pwd ne "$pass") { &error("管理用アイコンは管理者専用です。",'NOLOCK'); }
}
# ホスト名を取得
&get_host;
# 時間を取得
&get_time;
# クッキーを発行
&set_cookie;
# ファイルロック
if ($lockkey == 1) { &lock1; }
elsif ($lockkey == 2) { &lock2; }
# ログを開く
open(IN,"$logfile") || &error("Can't open $logfile");
@lines = ;
close(IN);
# 記事NO処理
$oya = $lines[0];
$oya =~ s/\n//;
shift(@lines);
# 二重投稿の禁止
local($flag) = 0;
foreach $line (@lines) {
($knum,$kk,$kd,$kname,$kem,$ksub,$kcom) = split(/<>/,$line);
if ($name eq "$kname" && $comment eq "$kcom") {
$flag=1; last;
}
}
if ($flag) { &error("二重投稿は禁止です"); }
# 親記事の場合、記事Noをカウントアップ
if ($FORM{'resno'} eq "") { $oya++; $number=$oya; }
else { $number = $oya; }
# 削除キーを暗号化
if ($FORM{'pwd'} ne "") { &passwd_encode($FORM{'pwd'}); }
# ログをフォーマット
$new_msg = "$number<>$FORM{'resno'}<>$date<>$name<>$email<>$subj<>$comment<>$url<>$host<>$ango<>$color<>$FORM{'icon'}<>\n";
## 自動ソート時は、レス記事投稿時は親記事はトップへ移動
if ($res_sort && $FORM{'resno'} ne "") {
@res_data = ();
@new = ();
foreach $line (@lines) {
$flag = 0;
($num,$k,$d,$na,$em,$sub,$com,$u,$ho,$p,$c,$ico) = split(/<>/,$line);
# 親記事を抜き出す
if ($k eq "" && $FORM{'resno'} eq "$num") {
$new_line = "$line";
$flag = 1;
}
# 関連のレス記事を抜き出す
elsif ($k eq "$FORM{'resno'}") {
push(@res_data,$line);
$flag = 1;
}
if ($flag == 0) { push(@new,$line); }
}
# 関連レス記事をトップへ
unshift(@new,@res_data);
# 新規メッセージをトップへ
unshift(@new,$new_msg);
# 親記事をトップへ
unshift(@new,$new_line);
## 親記事の場合、最大記事数を超える記事をカット
} elsif ($FORM{'resno'} eq "") {
$i = 0;
$stop = 0;
foreach $line (@lines) {
($num,$k,$d,$na,$em,$sub,$com,$u,$ho,$p,$c,$ico)=split(/<>/,$line);
if ($k eq "") { $i++; }
if ($i > $max-1) {
$stop = 1;
if ($pastkey == 0) { last; }
else {
if ($k eq "") { $kflag=1; push(@past_data,$line); }
else { push(@past_res,$line); }
}
}
if ($stop == 0) { push(@new,$line); }
}
## 過去記事生成
if ($kflag) {
@past_res = reverse(@past_res);
push(@past_data,@past_res);
&pastlog;
}
unshift(@new,$new_msg);
## レス記事は記事数の調整はしない
} else {
@res_data = ();
@new = ();
foreach $line (@lines) {
$flag = 0;
($num,$k,$d,$na,$em,$sub,$com,$u,$ho,$p,$c,$ico) = split(/<>/,$line);
# 親記事を抜き出す
if ($k eq "" && $FORM{'resno'} eq "$num") {
$new_line = "$line";
$flag = 2;
}
if ($flag == 0) { push(@new,$line); }
elsif ($flag == 2) {
push(@new,$new_line);
push(@new,$new_msg);
}
}
}
# 親記事NOを付加
unshift (@new,"$oya\n");
# ログを更新
open(OUT,">$logfile") || &error("Can't write $logfile");
print OUT @new;
close(OUT);
# ロック解除
if (-e $lockfile) { unlink($lockfile); }
# メール処理
if ($mailing && $mail_me) { &mail_to; }
elsif ($mailing && $email ne "$mailto") { &mail_to; }
}
## --- 返信フォーム
sub res_msg {
# ログを読み込み
open(DB,"$logfile") || &error("Can't open $logfile",'NOLOCK');
@lines = ;
close(DB);
# 親記事NOをカット
@lines = splice(@lines,1);
# フォーム長を定義
&get_agent;
# クッキーを取得
&get_cookie;
&header;
print "以下は、記事NO $FORM{'resno'} に関する返信フォームです。
\n";
print "\n";
print "\n";
$flag=0;
foreach $line (@lines) {
local($num,$k,$date,$name,$email,$sub,$com) = split(/<>/, $line);
# 親記事を出力
if ($k eq "" && $FORM{'resno'} eq "$num") {
$resub = $sub;
$flag=1;
print "【親記事】 \n";
print "$sub\n";
print "投稿者:$name\n";
print "投稿日:$date \n";
print " $com \n";
# レス記事を @res に格納
} elsif ($k ne "" && $FORM{'resno'} eq "$k") {
push(@res,$line);
}
}
# レス記事を表示
if (@res) {
# 記事を逆順に
@res = reverse(@res);
$flag = 0;
foreach $line (@res) {
local($num,$k,$date,$name,$email,$sub,$com) = split(/<>/,$line);
if ($flag == 0) {
$flag=1;
print " 【レス記事】 \n";
}
print "$sub\n";
print "投稿者:$name - \n";
print "$date \n";
print "$com \n";
}
}
# タイトル名
if ($resub eq "") { $resub = "Untitled"; }
if ($resub !=~ /^Re\:/) { $resub = "Re\: $resub"; }
print <<"EOM";
|
\n";
print "
\n";
&footer;
exit;
}
## --- フォームからのデータ処理
sub form_decode {
if ($ENV{'REQUEST_METHOD'} eq "POST") {
if ($ENV{'CONTENT_LENGTH'} > 51200) { &error("投稿量が大きすぎます。",'NOLOCK'); }
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 ($tagkey == 0) {
$value =~ s/\<\;/g;
$value =~ s/>/\>\;/g;
$value =~ s/\"/\"\;/g;
} else {
$value =~ s///g;
$value =~ s/<>/<\;>\;/g;
}
# 一括削除用
if ($name eq 'del') { push(@delete,$value); }
$FORM{$name} = $value;
}
$name = $FORM{'name'};
$comment = $FORM{'comment'};
$comment =~ s/\r\n/
/g;
$comment =~ s/\r|\n/
/g;
$email = $FORM{'email'};
$url = $FORM{'url'};
$url =~ s/^http\:\/\///;
$mode = $FORM{'mode'};
$subj = $FORM{'subj'};
$pwd = $FORM{'pwd'};
$icon = $FORM{'icon'};
$color = $FORM{'color'};
}
## --- 掲示板の使い方メッセージ
sub howto {
if ($tagkey == 0) { $tag_msg = "投稿内容には、タグは一切使用できません。\n"; }
else { $tag_msg = "コメント欄には、タグ使用をすることができます。\n"; }
&header;
print <<"HTML";
[掲示板にもどる]
- この掲示板はクッキー対応です。1度記事を投稿いただくと、おなまえ、Eメール、URL、削除キーの情報は2回目以降は自動入力されます。(ただし利用者のブラウザがクッキー対応の場合)
- $tag_msg
- 記事を投稿する上での必須入力項目は「おなまえ」と「メッセージ」です。Eメール、URL、題名、削除キーは任意です。
- 記事には、半角カナは一切使用しないで下さい。文字化けの原因となります。
- 記事の投稿時に「削除キー」にパスワード(英数字で8文字以内)を入れておくと、その記事は次回削除キーによって削除することができます。
- 記事の保持件数は最大 $max件です。それを超えると古い順に自動削除されます。
- 既存の記事に「返信」をすることができます。各記事の上部にある「返信」ボタンを押すと返信用フォームが現れます。
- 過去の投稿記事から「キーワード」によって簡易検索ができます。トップメニューの「ワード検索」のリンクをクリックすると検索モードとなります。
- 管理者が著しく不利益と判断する記事や他人を誹謗中傷する記事は\予\告\なく削除することがあります。
|
HTML
&footer;
exit;
}
## --- ワード検索サブルーチン
sub find {
&header;
print <<"HTML";
[掲示板にもどる]
- 検索したいキーワードを入力し、検索領域を選択して「検索ボタン」を押してください。
- キーワードは「半角スペース」で区切って複数指定することができます。
|
HTML
# ワード検索の実行と結果表示
if ($FORM{'word'} ne ""){
# 入力内容を整理
$cond = $FORM{'cond'};
$word = $FORM{'word'};
$word =~ s/ / /g;
$word =~ s/\t/ /g;
@pairs = split(/ /,$word);
# ファイルを読み込み
open(DB,"$logfile") || &error("Can't open $logfile",'NOLOCK');
@lines = ;
close(DB);
# 検索処理
foreach (1 .. $#lines) {
$flag = 0;
foreach $pair (@pairs){
if (index($lines[$_],$pair) >= 0) {
$flag = 1;
if ($cond eq 'or') { last; }
} else {
if ($cond eq 'and') { $flag = 0; last; }
}
}
if ($flag == 1) { push(@new,$lines[$_]); }
}
# 検索終了
$count = @new;
print "
検索結果:$count件\n";
print "
\n";
foreach $line (@new) {
($num,$k,$date,$name,$email,$sbj,$com,$url) = split(/<>/,$line);
if (!$sbj) { $sbj = "Untitled"; }
if ($email) { $name = "$name"; }
if ($url) { $url = "[HOME]"; }
if ($k) { $num = "$kへのレス"; }
# 結果を表示
print "- [$num] $sbj\n";
print "投稿者:$name $url 投稿日:$date\n";
print "
$com
\n";
}
print "
\n";
}
&footer;
exit;
}
## --- ブラウザを判断しフォーム幅を調整
sub get_agent {
# ブラウザ名を取得
$agent = $ENV{'HTTP_USER_AGENT'};
if ($agent =~ /MSIE 3/i) {
$nam_wid = 30;
$subj_wid = 40;
$com_wid = 65;
$url_wid = 48;
$nam_wid2 = 20;
} elsif ($agent =~ /MSIE 4/i || $agent =~ /MSIE 5/i) {
$nam_wid = 30;
$subj_wid = 40;
$com_wid = 65;
$url_wid = 78;
$nam_wid2 = 20;
} else {
$nam_wid = 20;
$subj_wid = 25;
$com_wid = 56;
$url_wid = 50;
$nam_wid2 = 10;
}
}
## --- クッキーの発行
sub set_cookie {
# クッキーは60日間有効
($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg,$ydayg,$isdstg)
= gmtime(time + 60*24*60*60);
$yearg += 1900;
if ($secg < 10) { $secg = "0$secg"; }
if ($ming < 10) { $ming = "0$ming"; }
if ($hourg < 10) { $hourg = "0$hourg"; }
if ($mdayg < 10) { $mdayg = "0$mdayg"; }
$month = ('Jan','Feb','Mar','Apr','May','Jun','Jul',
'Aug','Sep','Oct','Nov','Dec')[$mong];
$youbi = ('Sunday','Monday','Tuesday','Wednesday',
'Thursday','Friday','Saturday')[$wdayg];
$date_gmt = "$youbi, $mdayg\-$month\-$yearg $hourg:$ming:$secg GMT";
$cook="name\:$name\,email\:$email\,url\:$url\,pwd\:$pwd\,icon\:$icon\,color\:$color";
print "Set-Cookie: YYBBS=$cook; expires=$date_gmt\n";
}
## --- クッキーを取得
sub get_cookie {
@pairs = split(/\;/, $ENV{'HTTP_COOKIE'});
foreach $pair (@pairs) {
local($name, $value) = split(/\=/, $pair);
$name =~ s/ //g;
$DUMMY{$name} = $value;
}
@pairs = split(/\,/, $DUMMY{'YYBBS'});
foreach $pair (@pairs) {
local($name, $value) = split(/\:/, $pair);
$COOKIE{$name} = $value;
}
$c_name = $COOKIE{'name'};
$c_email = $COOKIE{'email'};
$c_url = $COOKIE{'url'};
$c_pwd = $COOKIE{'pwd'};
$c_icon = $COOKIE{'icon'};
$c_color = $COOKIE{'color'};
if ($FORM{'name'}) { $c_name = $FORM{'name'}; }
if ($FORM{'email'}) { $c_email = $FORM{'email'}; }
if ($FORM{'url'}) { $c_url = $url; }
if ($FORM{'pwd'}) { $c_pwd = $FORM{'pwd'}; }
if ($FORM{'icon'}) { $c_icon = $FORM{'icon'}; }
if ($FORM{'color'}) { $c_color = $FORM{'color'}; }
}
## --- エラー処理
sub error {
if ($_[1] ne '0') { &header; }
if (-e $lockfile && $_[1] eq "") { unlink($lockfile); }
print "
ERROR !
\n";
print "$_[0]\n";
print "
\n";
&footer;
exit;
}
## --- 削除画面
sub msg_del {
if ($FORM{'action'} eq 'admin' && $FORM{'pass'} ne "$pass") {
&error("パスワードが違います。",'NOLOCK');
}
open(DB,$logfile) || &error("Can't open $logfile",'NOLOCK');
@lines = ;
close(DB);
shift(@lines);
# 親記事のみの配列データを作成
@NEW = ();
foreach (@lines) {
($number,$k,$date,$name,$email,$subj,
$comment,$url,$host,$pwd) = split(/<>/, $_);
# レス記事を外す
if ($k eq '') { push(@NEW,$_); }
}
@lines = reverse(@lines);
&header;
print "[掲示板へ戻る]\n";
print "\n";
print "コメント削除画面 | \n";
print "
---|
\n";
print "\n";
print "\n";
if ($FORM{'action'} eq '') {
print "■投稿時に記入した「削除キー」により、記事を削除します。 \n";
}
print "■削除したい記事のチェックボックスにチェックを入れ、下記フォームに「削除キー」を入力してください。 \n";
print "■親記事を削除する場合、そのレスメッセージも同時に消滅してしまうことになりますので、ご注意ください。 \n";
print " |
\n";
print "
\n";
print "
\n";
&footer;
exit;
}
## --- 記事削除処理
sub usr_del {
if ($FORM{'del_key'} eq "") { &error("削除キーが入力モレです。",'NOLOCK'); }
if ($FORM{'del'} eq "") { &error("ラジオボタンの選択がありません。",'NOLOCK'); }
# ロック開始
if ($lockkey == 1) { &lock1; }
elsif ($lockkey == 2) { &lock2; }
# ログを読み込む
open(DB,"$logfile") || &error("Can't open $logfile");
@lines = ;
close(DB);
# 親記事NO
$oya = $lines[0];
if ($oya =~ /<>/) { &error("ログが正しくありません。"); }
shift(@lines);
## 削除キーによる記事削除 ##
@new=();
foreach $line (@lines) {
$dflag = 0;
($num,$k,$dt,$name,$email,$sub,$com,$url,$host,$pw) = split(/<>/,$line);
if ($FORM{'del'} eq "$dt") {
$dflag = 1;
$encode_pwd = $pw;
$del_num = $num;
if ($k eq '') { $oyaflag=1; }
} elsif ($oyaflag && $del_num eq "$k") {
$dflag = 1;
}
if ($dflag == 0) { push(@new,$line); }
}
if ($del_num eq '') { &error("$FORM{'del'}削除対象記事が見つかりません。"); }
else {
if ($encode_pwd eq '') { &error("削除キーが設定されていません。"); }
$plain_text = $FORM{'del_key'};
&passwd_decode($encode_pwd);
if ($check eq 'no') { &error("パスワードが違います。"); }
}
# 親記事NOを付加
unshift(@new,$oya);
## ログを更新 ##
open(DB,">$logfile") || &error("Can't write $logfile");
print DB @new;
close(DB);
# ロック解除
if (-e $lockfile) { unlink($lockfile); }
# 削除画面にもどる
&msg_del;
}
## --- 管理者一括記事削除
sub admin_del {
if ($FORM{'pass'} ne "$pass") { &error("パスワードが違います。",'NOLOCK'); }
if ($FORM{'del'} eq "") { &error("チェックボックスの選択がありません。",'NOLOCK'); }
# ロック開始
if ($lockkey == 1) { &lock1; }
elsif ($lockkey == 2) { &lock2; }
# ログを読み込む
open(DB,"$logfile") || &error("Can't open $logfile");
@lines = ;
close(DB);
# 親記事NO
$oya = $lines[0];
if ($oya =~ /<>/) {
&error("ログが正しくありません。\(v2.5以前のログの場合は変換の必要があります\)<\/small>");
}
shift(@lines);
## 削除処理
foreach $line (@lines) {
$dflag=0;
($num,$k,$dt,$name,$email,$sub,$com,$url,$host,$pw) = split(/<>/,$line);
foreach $del (@delete) {
if ($del eq "$dt") {
$dflag = 1;
$del_num = $num;
if ($k eq '') { $oyaflag=1; }
} elsif ($oyaflag && $del_num eq "$k") {
$dflag = 1;
}
}
if ($dflag == 0) { push(@new,$line); }
}
# 親記事NOを付加
unshift(@new,$oya);
## ログを更新 ##
open(DB,">$logfile") || &error("Can't write $logfile");
print DB @new;
close(DB);
# ロック解除
if (-e $lockfile) { unlink($lockfile); }
# 削除画面にもどる
&msg_del;
}
## --- 管理者入室画面
sub admin {
&header;
print "パスワードを入力してください。
\n";
print "
\n";
&footer;
exit;
}
## --- 時間を取得
sub get_time {
$ENV{'TZ'} = "JST-9";
($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time);
$year = 1900 + $year;
$mon++;
if ($mon < 10) { $mon = "0$mon"; }
if ($mday < 10) { $mday = "0$mday"; }
if ($hour < 10) { $hour = "0$hour"; }
if ($min < 10) { $min = "0$min"; }
if ($sec < 10) { $sec = "0$sec"; }
$week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat') [$wday];
# 日時のフォーマット
$date = "$year\/$mon\/$mday\($week\) $hour\:$min\:$sec";
}
## --- カウンタ処理
sub counter {
# カウントファイルを読みこみ
open(NO,"$cntfile") || &error("Can't open $cntfile",'0');
$cnt = ;
close(NO);
# 閲覧時のみカウントアップ
if ($FORM{'mode'} eq '') {
# カウントアップ
$cnt++;
# テンポラリーファイルを定義
$prono = "$$";
if ($prono eq "") {
srand;
$prono = 1000000000000000 * rand;
}
$cnt_temp = "$lock_dir\/$prono\.tmp";
# テンポラリーファイルを作成
open(TMP,">$cnt_temp") || &error("Can't create tempfile",'0');
print TMP $cnt;
close(TMP);
# パーミッションを666に
chmod (0666,"$cnt_temp");
# リネームする
rename($cnt_temp,$cntfile);
# もしテンポラリーファイルが残っていたら削除
if (-e $cnt_temp) { unlink($cnt_temp); }
}
# 桁数調整
while(length($cnt) < $mini_fig) { $cnt = '0' . "$cnt"; }
@cnts = split(//,$cnt);
print "\n";
# GIFカウンタ表示
if ($counter == 2) {
foreach (0 .. $#cnts) {
print "";
}
# テキストカウンタ表示
} else {
print "$cnt";
}
print " |
\n";
}
## --- ロックファイル(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 {
open(LOCK,">$lockfile");
close(LOCK);
$flag = 1;
last;
}
}
if ($flag == 0) { &error("LOCK is BUSY"); }
}
## --- メール送信
sub mail_to {
$mail_subj = "$title に投稿がありました。";
&jcode'convert(*mail_subj,'jis');
&jcode'convert(*name,'jis');
&jcode'convert(*subj,'jis');
&jcode'convert(*comment,'jis');
$comment =~ s/
/\n/g;
$comment =~ s/<//g;
if (open(MAIL,"| $sendmail $mailto")) {
print MAIL "X-Mailer: YYBBS MAILER\n";
print MAIL "To: $mailto\n";
# メールアドレスがない場合はダミーメールに置き換え
if ($email eq "") { $email = "nomail\@xxx.xxx"; }
print MAIL "From: $email\n";
print MAIL "Subject: $mail_subj\n";
print MAIL "Content-Transfer-Encoding: 7bit\n";
print MAIL "Content-type: text/plain\n\n";
print MAIL "$mail_subj\n";
print MAIL "--------------------------------------------------------\n";
print MAIL "TIME : $date\n";
print MAIL "HOST : $host\n";
print MAIL "NAME : $name\n";
print MAIL "EMAIL: $email\n";
if ($url) { print MAIL "URL : http://$url\n"; }
if ($subj eq "") { $subj = "Untitled"; }
print MAIL "TITLE: $subj\n\n";
print MAIL "$comment\n";
print MAIL "--------------------------------------------------------\n";
close(MAIL);
}
}
## --- パスワード暗号処理
sub passwd_encode {
$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];
$ango = crypt($_[0], $nsalt);
}
## --- パスワード照合処理
sub passwd_decode {
if ($_[0] =~ /^\$1\$/) { $crptkey = 3; } # FreeBSDサーバ対応
else { $crptkey = 0; }
$check = "no";
if (crypt($plain_text, substr($_[0],$crptkey,2)) eq "$_[0]") {
$check = "yes";
}
}
## --- HTMLのヘッダー
sub header {
print "Content-type: text/html\n\n";
print "\n\n";
print "\n";
print "$title\n";
# bodyタグ
if ($backgif) { $bgkey = "background=\"$backgif\" bgcolor=$bgcolor"; }
else { $bgkey = "bgcolor=$bgcolor"; }
print "\n";
}
## --- HTMLのフッター
sub footer {
## MakiMakiさんの画像使用の有無に関わらずこの2箇所のリンク部を
## 削除することはできません。
print "
\n";
print "KENT & \n";
print "MakiMaki\n";
print "\n";
print "\n";
}
## --- 自動リンク
sub auto_link {
$_[0] =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\+\=\:\@\%\;\#]+)/$1$2<\/a>/g;
}
## --- イメージ画像表示
sub image {
&header;
print "
\n";
print "イメージ画像サンプル
\n";
print "現在登録されているイメージ画像は以下のとおりです。\n";
print "
\n";
print "\n";
foreach (0 .. $#icon1) {
print "$icon2[$_] | \n";
print " |
\n";
}
print "
\n
\n";
&footer;
exit;
}
## --- ホスト名取得
sub get_host {
$host = $ENV{'REMOTE_HOST'};
$addr = $ENV{'REMOTE_ADDR'};
if ($get_remotehost) {
if ($host eq "" || $host eq "$addr") {
($p1,$p2,$p3,$p4) = split(/\./,$addr);
$temp = pack("C4",$p1,$p2,$p3,$p4);
$host = gethostbyaddr($temp, 2);
}
if ($host eq "") { $host = $addr; }
}
}
## --- 過去ログ生成
sub pastlog {
$new_flag = 0;
# 過去NOを開く
open(NO,"$nofile") || &error("Can't open $nofile");
$count = ;
close(NO);
# 過去ログのファイル名を定義
$pastfile = "$past_dir\/$count\.html";
# 過去ログがない場合、新規に自動生成する
unless(-e $pastfile) { &new_log; }
# 過去ログを開く
if ($new_flag == 0) {
open (IN,"$pastfile") || &error("Can't open $pastfile");
@past = ;
close(IN);
}
# 規定の行数をオーバーすると、次ファイルを自動生成する
if ($#past > $log_line) { &next_log; }
foreach $pst_line (@past_data) {
($pnum,$pk,$pdt,$pname,$pemail,
$psub,$pcom,$purl,$phost,$ppw) = split(/<>/, $pst_line);
if ($psub eq "") { $psub = "Untitled"; }
if ($pemail) { $pname = "$pname"; }
if ($purl) { $purl="http://$purl"; }
if ($pk) { $pnum = "$pkへのレス"; }
# 自動リンク
if ($autolink) { &auto_link($pcom); }
# 保存記事をフォーマット
$html = <<"HTML";
[$pnum] $psub 投稿者:$pname 投稿日:$pdt$pcom$purl
HTML
push(@htmls,"$html");
}
@news = ();
foreach $line (@past) {
if ($line =~ //i) { last; }
push (@news,$line);
if ($line =~ //i) { push (@news,@htmls); }
}
push (@news,"\n