#!/usr/local/bin/perl ## ----------------------------------------------------------------------------+ ## YY-BOARD v2.1 ## by おいどん (99/01/30) ## E-MAIL: oidon@iod.co.jp ## WWW: http://www.iod.co.jp/~oidon/ $ver = 'YYBBS v2.1'; # バージョン情報(修正不要) ## ---[注意事項ほか]-----------------------------------------------------------+ ## 1.削除キーの暗号化には Crypt関数を使用しています。プロバイダがCrypt関数に対応 ## していない場合は、コメント削除機能は使用できません。 ## 2.投稿があるとメール通知したい場合($mailing=1;)、プロバイダがsendmailを許可 ##  している場合のみです。(例:BIGLOBE,SO-NETは可能、InfoWeb,RIMNETは不可) ## 3.このスクリプトはフリーソフトです。このスクリプトを使用したいかなる損害に ## 対して作者は一切の責任を負いません。 ## 4.設置に関する質問はサポート掲示板にお願いいたします。メールによる質問には ## お答えできません。 ## ----------------------------------------------------------------------------+ require './jcode.pl'; # jcode.plが同一ディレクトリにある場合 ### --- 基本設定 --- ### $title = "掲示板"; # タイトル名 $t_color = "9900cc"; # タイトルの色 $t_size = 7; # タイトルの大きさ(font size) $t_face = "MS Pゴシック"; # タイトル文字の種類(font face) $backgif = ""; # 壁紙を指定 $bgcolor = "#faeaff"; # 背景色を指定 $text = "#000000"; # 文字色を指定 $link = "#0000FF"; # リンク色を指定(未リンク) $vlink = "#800080"; # リンク色を指定(既リンク) $alink = "#FF0000"; # リンク色を指定(リンク中) $homepage = 'http://contest.thinkquest.gr.jp/tqj1998/10098/frame/mokuji.html'; # 戻り先のURL(index.htmlなど) $homepage2 = 'http://contest.thinkquest.gr.jp/tqj1998/10098/noframe/mokuji.html'; # 戻り先のURL(index.htmlなど) $max = 100; # 親記事最大数 (あまり多くすると危険) $pass = 'jom578'; # 管理者用マスタパスワード(英数字) ### --- 応用設定(ここからは場合に応じての設定内容)--- ### $icon_mode = 0; # アイコンモード (0=no 1=yes) $res_sort = 0; # 返信がつくと親記事をトップへ移動 (0=no 1=yes) $title_gif = '.'; # タイトルにGIF画像を使用する時 (http://から記述) $tg_w = '150'; # 上記タイトルGIF画像の幅(ピクセル) $tg_h = '50'; # 〃 高さ(ピクセル) $lockkey = 0; # ファイルロック形式(0=no 1=symlink関数 2=open関数) $lockfile = './yybbs.lock'; # ロックファイル名 $counter = 0; # ミニカウンタの設置 (0=no 1=yes) $mini_fig = 5; # ミニカウンタの桁数 $cnt_color = "#dd0000"; # テキストのとき:ミニカウンタの色 $gif_path = "."; # GIFのとき :画像までのディレクトリ $mini_w = 8; # 〃  :画像の横サイズ $mini_h = 12; # 〃  :画像の縦サイズ $countfile = './count.dat'; # カウンタファイル $tagkey = 0; # タグの許可(0=no 1=yes) $script = './yybbs.cgi'; # スクリプトファイル $logfile = './yybbs.log'; # ログファイル $sbj_color = "#9933ff"; # 記事の[タイトル]部の色 $nam_color = "#9933ff"; # 記事の[名前]部の色 $tbl_color = "#FFFFFF"; # 記事表示部の下地の色 $obi_color = "#660099"; # 使い方説明/ワード検索画面のタイトルバックの色 $home_wid = 25; # home.gifの画像横サイズ $home_hei = 22; # 〃 縦サイズ $method = 'POST'; # methodの形式 (POST/GET) $pagelog = 10; # 1ページ当たりの記事表示数 (親記事) $mailing = 0; # 投稿があるとメール通知する(0=no 1=yes) $mailto = 'yumiko@sa2.son-net.or.jp'; # メールアドレス(メール通知する時) $sendmail = '/usr/lib/sendmail'; # sendmailパス(メール通知する時) $base_url = "."; # 他サイトから投稿排除時に指定(http://から書く) # ↓文字色の設定。 @COLORS = ('000000','DF0000','008040','0000FF','C100C1','FF80C0','FF8040','000080'); $wrap = 'soft'; # 投稿フォーム改行形式 (soft=手動 hard=強制) $autolink = 1; # 自動リンク (0=no 1=yes) $pastkey = 0; # 過去ログ生成 (0=no 1=yes) $nofile = "./pastno.dat"; # 過去ログ用NOファイル $past_dir = "."; # 過去ログのディレクトリ $log_line = '150'; # 過去ログ1ファイルの行数 $yybbs2 = "./yybbs2.cgi"; # 過去ログ管理ファイル ## 設定ここまで ### --- メイン処理 --- ### &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"); @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 '.' || $title_gif eq '') { print "
"; print "$title\n"; } else { print "
\n"; } print "
\n"; print "[目次(Normal)へ]\n"; print "[目次(Light)へ]\n"; print "[掲示板の使い方]\n"; print "[ワード検索]\n"; if ($pastkey) { print "[過去ログ]\n"; } print <<"EOM"; [記事削除] [管理用]
EOM if ($icon_mode) { print "\n"; } print "\n"; print "\n"; print "
おなまえ
Eメール
題  名  
コメント
URL
イメージ (あなたのイメージを選択して下さい)\n"; print "[画像イメージ参照]
削除キー\n"; print "(自分の記事を削除時に使用。英数字で8文字以内)
文字色\n"; # クッキーの色情報がない場合 if ($c_color eq "") { print "\n"; print "\n"; foreach (1 .. $#COLORS) { print "\n"; print "\n"; } # クッキーの色情報がある場合 } else { foreach (0 .. $#COLORS) { if ($c_color eq "$COLORS[$_]") { print "\n"; print "\n"; } else { print "\n"; print "\n"; } } } print "

\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,$subj,$comment,$url,$host,$pwd, $color,$icon) = split(/<>/,$new[$_]); if ($email) { $name = "$name"; } if ($subj eq "") { $subj = "(無題)"; } if ($url) { $url = ""; } print <<"EOM";
[$number] $subj  投稿者:$name  投稿日:$date $url
EOM $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 = "(無題)"; } print "
\n"; if ($rurl ne "") { print "\n"; } # 自動リンク if ($autolink) { &auto_link($rcom); } print "
$rsub \n"; print "投稿者:$rname - \n"; print "$rd
\n"; print "$rcom
\n"; } } print "

\n"; } print "\n"; # 改頁処理 $next_line = $page_end + 1; $back_line = $page - $pagelog; # 前頁処理 if ($back_line >= 0) { print "\n"; } # 次頁処理 if ($page_end ne "$end_data") { print "\n"; } print "
\n"; print "\n"; print "\n"; print "
\n"; print "\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 !~ $base_url) { &error("不正なアクセスです。"); } } # 名前とコメントは必須 if ($FORM{'name'} eq "") { &error("名前が入力されていません。"); } if ($FORM{'comment'} eq "") { &error("コメントが入力されていません。"); } # ホスト名を取得 $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; 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; } } # クッキーを発行 &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 == 1 && $FORM{'email'} ne $mailto) { &mailto; } } ### --- 返信フォーム --- ### sub res_msg { # ログを読み込み open(DB,"$logfile") || &error("Can't open $logfile"); @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 = "無題"; } if ($resub !=~ /^Re\:/) { $resub = "Re\: $resub"; } print <<"EOM";

EOM if ($icon_mode) { print "\n"; } print "\n"; print "
おなまえ
Eメール
タイトル
メッセージ
URL
イメージ (あなたのイメージを選択して下さい)\n"; print "[イメージ画像参照]
削除キー"; print "\n"; print "(自分の記事を削除時に使用。英数字で8文字以内)
文字色\n"; # クッキーの色情報がない場合 if ($c_color eq "") { print "\n"; foreach (1 .. $#COLORS) { print "\n"; } # クッキーの色情報がある場合 } else { foreach (0 .. $#COLORS) { if ($c_color eq "$COLORS[$_]") { print "\n"; } else { print "\n"; } } } print "
\n


\n"; &footer; exit; } ### --- フォームからのデータ処理 --- ### sub form_decode { if ($ENV{'REQUEST_METHOD'} eq "POST") { if ($ENV{'CONTENT_LENGTH'} > 51200) { &error("投稿量が大きすぎます。"); } 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; } 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'}; # 日時の取得 $ENV{'TZ'} = "JST-9"; ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time); if ($year < 10) { $year = "0$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 howto { if ($tagkey == 0) { $tag_msg = "投稿内容には、タグは一切使用できません。\n"; } else { $tag_msg = "コメント欄には、タグ使用をすることができます。\n"; } &header; print <<"HTML"; [掲示板にもどる]
掲示板の利用上の注意

  1. この掲示板はクッキー対応です。1度記事を投稿いただくと、おなまえ、Eメール、URL、削除キーの情報は2回目以降は自動入力されます。(ただし利用者のブラウザがクッキー対応の場合)

  2. $tag_msg

  3. 記事を投稿する上での必須入力項目は「おなまえ」「メッセージ」です。Eメール、URL、題名、削除キーは任意です。

  4. 記事には、半角カナは一切使用しないで下さい。文字化けの原因となります。

  5. 記事の投稿時に「削除キー」にパスワード(英数字で8文字以内)を入れておくと、その記事は次回削除キーによって削除することができます。

  6. 記事の保持件数は最大 $max件です。それを超えると古い順に自動削除されます。

  7. 既存の記事に「返信」をすることができます。各記事の上部にある「返信」ボタンを押すと返信用フォームが現れます。

  8. 過去の投稿記事から「キーワード」によって簡易検索ができます。トップメニューの「ワード検索」のリンクをクリックすると検索モードとなります。

  9. 管理者が著しく不利益と判断する記事や他人を誹謗中傷する記事は\予\告\なく削除することがあります。

HTML &footer; exit; } ### --- ワード検索サブルーチン --- ### sub find { &header; print <<"HTML"; [掲示板にもどる]
ワード検索

  • 検索したいキーワードを入力し、検索領域を選択して「検索ボタン」 を押してください。
  • キーワードは「半角スペース」で区切って複数指定することができます。

キーワード
検索条件 AND OR
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"); @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,$subj,$com,$url) = split(/<>/,$line); if ($subj eq "") { $subj = "no title"; } if ($email) { $name = "$name"; } if ($url) { $url = "http://$url"; } # 結果を表示 print "
  1. [$num] $subj\n"; print "投稿者:$name 投稿日:$date

    \n"; print "

    $com

    $url


    \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) { $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 { ($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg,$ydayg,$isdstg) = gmtime(time + 30*24*60*60); if ($yearg < 10) { $yearg = "0$yearg"; } 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 (-e $lockfile) { unlink($lockfile); } if ($_[1] ne '0') { &header; } print "


システムエラー発生!

\n"; print "

$_[0]\n"; print "


\n"; &footer; exit; } ### --- 削除画面 --- ### sub msg_del { if ($FORM{'action'} eq 'admin' && $FORM{'pass'} ne "$pass") { &error("パスワードが違います。"); } open(DB,$logfile) || &error("Can't open $logfile"); @lines = ; close(DB); # 親記事のみの配列データを作成 @NEW = (); foreach (1 .. $#lines) { ($number,$k,$date,$name,$email,$subj,$comment,$url,$host,$pwd) = split(/<>/,$lines[$_]); $flag = 0; # レス記事を外す if ($k > 0) { $flag = 1; } if ($flag == 0) { push(@NEW,$lines[$_]); } } @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"; if ($FORM{'action'} eq '') { print "\n"; print "削除キー \n"; } else { print "\n"; print "\n"; print "\n"; } print "\n"; print "

\n"; print "\n"; if ($FORM{'action'} eq 'admin') { print "\n"; } print "\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) { ($num,$k,$date,$name,$email,$sub,$com,$url,$host,$pw,$color) = split(/<>/,$NEW[$_]); if ($email ne "") { $name="$name"; } if ($sub eq "") { $sub = "(無題)"; } $com =~ s/
/ /g; if ($tagkey) { $com =~ s//>/g; } if (length($com) > 60) { $com = substr($com,0,58); $com = $com . '..'; } if ($FORM{'action'} eq 'admin') { print "\n"; } else { print "\n"; } print "\n"; print "\n"; if ($FORM{'action'} eq 'admin') { print "\n"; } print "\n"; ## レスメッセージを表示 foreach (1 .. $#lines) { ($rnum,$rk,$rd,$rname,$rem,$rsub,$rcom,$rurl,$rho,$rp,$rc) =split(/<>/,$lines[$_]); $rcom =~ s/
/ /g; if ($tagkey) { $rcom =~ s//\>\;/g; } if (length($rcom) > 60) { $rcom=substr($rcom,0,58); $rcom=$rcom . '..'; } if ($num eq "$rk") { if ($FORM{'action'} eq 'admin') { print "\n"; } else { print "\n"; } print "\n"; print "\n"; if ($FORM{'action'} eq 'admin') { print "\n"; } print "\n"; } } } print "
削除記事No題名投稿者投稿日コメントホスト名
$num$sub$name$date$com$host
$numへのレス$rname$rd$rcom$rho

\n"; print "\n"; # 改頁処理 $next_line = $page_end + 1; $back_line = $page - $pagelog; # 前頁処理 if ($back_line >= 0) { print "\n"; } # 次頁処理 if ($page_end ne $end_data) { print "\n"; } print "
\n"; print "\n"; print "\n"; print "\n"; if ($FORM{'action'} eq 'admin') { print "\n"; print "\n"; } print "
\n"; print "\n"; print "\n"; print "\n"; if ($FORM{'action'} eq 'admin') { print "\n"; print "\n"; } print "


\n"; &footer; exit; } ### --- 記事削除処理 --- ### sub usr_del { if ($FORM{'del_key'} eq "") { &error("削除キーが入力モレです。"); } if ($FORM{'del'} eq "") { &error("ラジオボタンの選択がありません。"); } # ロック開始 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); @lines = reverse(@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を付加 @new = reverse(@new); 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("パスワードが違います。"); } if ($FORM{'del'} eq "") { &error("チェックボックスの選択がありません。"); } # ロック開始 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); @lines = reverse(@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を付加 @new = reverse(@new); 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"; print "\n"; print "\n"; print "\n"; print "


\n"; &footer; exit; } ### --- カウンタ処理 sub counter { # カウントファイル読み込み open(NO,"$countfile") || &error("Can't open $countfile",'0'); $cnt = ; close(NO); # カウントアップ if ($FORM{'mode'} eq "") { $cnt++; # カウントファイル更新 open(NO,">$countfile") || &error("Can't write $countfile",'0'); eval 'flock(NO,2);'; print NO $cnt; eval 'flock(NO,8);'; close(NO); } # 桁数調整 while(length($cnt) < $mini_fig) { $cnt = '0' . "$cnt"; } @cnts = split(//,$cnt); print "
\n"; # カウンタ表示 if (-e "$gif_path/0.gif") { foreach (0 .. $#cnts) { print "\"$cnts[$_]\""; } } 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 mailto { $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; open(MAIL,"| $sendmail -t") || &error("Can't post sendmail"); print MAIL "X-Mailer: YYBBS MAILER\n"; print MAIL "To: $mailto\n"; # メールアドレスがない場合はダミーメールに置き換え if ($FORM{'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"; print MAIL "\n\n"; print MAIL "$mail_subj\n"; print MAIL "--------------------------------------------------------\n"; print MAIL "TIME : $date\n"; print MAIL "NAME : $name\n"; print MAIL "EMAIL: $FORM{'email'}\n"; if ($url ne "") { print MAIL "URL : http://$url\n"; } if ($FORM{'resno'} ne "") { $subj = "(Res Message)"; } elsif ($FORM{'resno'} eq "" && $subj eq "") { $subj = "no title"; } print MAIL "TITLE: $subj\n\n"; print MAIL "$comment\n\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 "OIDON & \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 "\n"; print "\n"; } print "
$icon2[$_]
\n


\n"; &footer; exit; } ### --- 過去ログ生成 --- ### 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; } # $pst_line = $lines[$max-1]; # $pst_line =~ s/\n//g; # @past_data = reverse(@past_data); foreach $pst_line (@past_data) { ($pnum,$pk,$pdt,$pname,$pemail,$psub,$pcom,$purl,$phost,$ppw) = split(/<>/, $pst_line); if ($psub eq "") { $psub = "(無題)"; } 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\n"); # 過去ログを更新 open(OUT,">$pastfile") || &error("Can't write $pastfile"); print OUT @news; close(OUT); } ## 過去ログ次ファイル生成ルーチン sub next_log { # 次ファイルのためのカウントアップ $count++; # カウントファイル更新 open(NO,">$nofile") || &error("Can't write $nofile"); print NO "$count"; close(NO); $pastfile = "$past_dir/$count\.html"; &new_log; } ## 新規過去ログファイル生成ルーチン sub new_log { $new_flag = 1; if ($backgif) { $bgkey = "background=\"$backgif\" bgcolor=$bgcolor"; } else { $bgkey = "bgcolor=$bgcolor"; } $past[0] = "過去ログ\n"; $past[1] = "
\n"; $past[2] = "<\!--HAJIME-->\n"; $past[3] = "<\!--OWARI-->\n"; $past[4] = "\n"; # 新規過去ログファイルを生成更新 open(OUT,">$pastfile") || &error("Can't write $pastfile"); print OUT @past; close(OUT); # パーミッションを666へ。 chmod(0666,"$pastfile"); }