#!/usr/bin/perl #┌───────────────────────────────── #│ LIGHT BOARD - light.cgi (2005/11/20) #│ Copyright (c) KentWeb #│ webmaster@kent-web.com #│ http://www.kent-web.com/ #│ #│ Modified by isso. May, 2006 #│ http://swanbay-web.hp.infoseek.co.jp/index.html #└───────────────────────────────── # 外部ファイル取り込み require './jcode.pl'; require './init.cgi'; if($writevalue eq $postvalue) { &error("\$writevalueと\$postvalueの文字は同じにしないでください"); } &agent; &decode; &setfile; &previewcheck; if ($mode eq "$writevalue" && $in{'pview'} ne "on") { ®ist; } elsif ($mode eq "$postvalue" && $in{'pview'} eq "on") { ®ist; } elsif ($mode eq "$writevalue" && $in{'pview'} eq "on") { &error("$spammsg"); } elsif ($mode eq "previewmode") { &previewmode("$timecheck"); } elsif ($mode eq "howto") { &howto; } elsif ($mode eq "find") { &find; } elsif ($mode eq "dellog") { &dellog; } elsif ($mode eq "editlog") { &editlog; } elsif ($mode eq "past" && $pastkey) { &pastlog; } elsif ($mode eq "check") { ✓ } elsif ($in{'pass'} eq $pass && $mode eq "admin_repost") { ®ist; } elsif ($mode eq 'noscript') { &noscript; } &viewlog; #------------------------------------------------- # 記事表示 #------------------------------------------------- sub viewlog { local($x,$y,$i,$flag,$no,$dat,$nam,$eml,$sub,$com,$url,$resub,$recom,$nexr,$back); # クッキー取得 local($cnam,$ceml,$curl,$cpwd) = &get_cookie; # $curl ||= "http://"; # タイトル表示 &header; print "
\n"; if ($t_img) { print "\"$title\"\n"; } else { print "$title\n"; } if ( (-s $spamlogfile) > $spamlog_maxfile ) { print "
\n
\n投稿拒否ログ(スパムログ)のファイルサイズが大きくなりました。
", "至急、管理モードから投稿拒否ログを削除して下さい。

\n
\n"; } # 表示開始 print <<"EOM";
[トップに戻る] [留意事項] [ワード検索] EOM # 過去ログリンク print "[過去ログ]\n" if ($pastkey); # ログ編集機能のリンク print "[管理用]\n"; # 返信モード $resub=''; $recom=''; if ($in{'res'}) { # 引用記事抽出 open(IN,"$logfile") || &error("Open Error: $logfile"); while () { ($no,$dat,$nam,$eml,$sub,$com) = split(/<>/); last if ($in{'res'} == $no); } close(IN); # コメントに引用符付加 $recom = "> $com"; $recom =~ s/
/\n> /g; # 題名に引用項目付加 $sub =~ s/^Re://; $resub = "Re:[$in{'res'}] $sub"; } # 投稿フォーム local $access = &encode_bbsmode(); local $enaddress = &encode_addr(); if ($keychange) { $url_key = 'email'; $mail_key = 'url'; } else { $url_key = 'url'; $mail_key = 'email'; } print <<"EOM";
EOM if ($type eq 'p') { if ($javascriptpost) { print < EOM } else { print "\n"; } } else { print "\n"; } print < // -->
おなまえ
Eメール EOM if ($no_email eq '1') { print "メールアドレスは入力禁止"; } elsif ($no_email eq '2') { print "入力する場合には必ず@を全角で書いて下さい"; } print <
タイトル EOM if (!$referercheck || $ENV{'HTTP_REFERER'}) { print " \n"; if ($type eq 'p') { if ($javascriptpost) { print < EOM } else { print ""; } } else { print ""; } } else { print "
\n掲示板へ直接アクセスした場合には投稿できません。", "トップページから入り直してください。\n"; } print <
コメント EOM if ($comment_url) { print "【コメント中のURLは先頭のhを抜いて書き込んで下さい。】"; } print <
EOM $f_c_d = int(rand(5E07)) + 11E08; if ($urlcheck) { print " メッセージ中には参照先URLと同じURLを書き込まないで下さい\n"; } print <
参照先
暗証キー (記事メンテ用)
EOM # 記事展開 $i=0; open(IN,"$logfile") || &error("Open Error: $logfile"); while () { $i++; if ($i < $page + 1) { next; } if ($i > $page + $plog) { next; } ($no,$dat,$nam,$eml,$sub,$com,$url) = split(/<>/); # $nam = "$nam" if ($eml); if ($eml) { ($em0,$em1) = split(/\@/,$eml); $em1 =~ s/\./&\#46\;/g; $nam = "\n". "\n"; } &auto_link($com) if ($link); $com =~ s/([>]|^)(>[^<]*)/$1$2<\/font>/g; $com .= "

$url" if ($url); # 記事編集 print "


[$no] "; print "$sub 投稿者:$nam "; print "投稿日:$dat  "; print "
\n"; print "\n"; print "

\n"; print "
$com

\n"; } close(IN); print "

\n"; $next = $page + $plog; $back = $page - $plog; $flag=0; print "

\n"; if ($back >= 0) { $flag=1; print "\n"; } if ($next < $i) { $flag=1; print "\n"; } # ページ移動ボタン表示 if ($flag) { print ""; } print <<"EOM";
\n"; print "\n"; print "
\n"; print "\n"; print "
"; $x=1; $y=0; while ($i > 0) { if ($page == $y) { print "[$x]\n"; } else { print "[$x]\n"; } $x++; $y += $plog; $i -= $plog; } print "

処理 記事No 暗証キー
- LightBoard - Modified by isso
EOM exit; } #------------------------------------------------- # 投稿受付 #------------------------------------------------- sub regist { local($pwd,$past,@w,@past,@file); local($cnam,$ceml,$curl,$cpwd) = &get_cookie; # 拡張オプションチェック if ($mode ne "admin_repost") { &option_check($in{'pwd'},$in{'email'},$in{'comment'},$in{'url'}); } if ($in{'email'} && $in{'email'} =~ /@/) { $in{'email'} =~ s/@/\@/; } # 入力チェック if (!$post_flag) { &error("不正なアクセスです"); } if ($in{'name'} eq "") { &error("名前が入力されていません"); } if ($in{'comment'} eq "") { &error("コメントが入力されていません"); } if ($in{'email'}) { if ($in{'email'} !~ /https?\:\/\//i) { if ($in{'email'} !~ /^[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,6}$/) { &error("Eメールの入力内容が正しくありません"); } } } if ($in{'url'} eq "http://") { $in{'url'}=""; } if (!$in{'sub'}) { if ($suberror) { &error("タイトルが入力されていません"); } else { $in{'sub'} = "無題"; } } # ファイルロック &lock if ($lockkey); # ログを開く open(IN,"$logfile") || &error("Open Error: $logfile"); @file = ; close(IN); # 二重投稿禁止 local($no,$dat,$nam,$eml,$sub,$com,$url,$ho,$pw,$tim) = split(/<>/, $file[0]); if ($host eq $ho && $wait > time - $tim) { &error("連続投稿はもうしばらく時間を置いてください"); } if ($in{'name'} eq $nam && $in{'comment'} eq $com) { &error("二重投稿は禁止です"); } # 暗証キーを暗号化 if ($mode ne "admin_repost") { if ($in{'pwd'} ne "") { $pwd = &encrypt($in{'pwd'}); } } # 時間を取得 local($min,$hour,$mday,$mon,$year,$wday) = (localtime(time))[1..6]; @w = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); $date = sprintf("%04d/%02d/%02d(%s) %02d:%02d", $year+1900,$mon+1,$mday,$w[$wday],$hour,$min); # 改行・ダブルクオート復元 if ($in{'pview'} eq "on") { $in{'comment'} =~ s/<br>/
/g; $in{'comment'} =~ s/"/"/g; } # スパム投稿チェック ($spam,$reason) = &spam_check($in{'url2'},$in{"$bbscheckmode"},$in{'comment'}, $in{'reno'},$in{'url'},$in{'email'},$in{'sub'},$in{'mail'},$in{"$formcheck"},$cnam, $in{'subject'},$in{'title'},$in{'theme'},$ENV{'HTTP_ACCEPT_LANGUAGE'},$ENV{'HTTP_USER_AGENT'}); # プレビュー&スパムログの削除 if ($in{'pview'} eq "on" || $mode eq "admin_repost") { if ($spamlog) { &del_spamlog("$in{\"$bbscheckmode\"}"); } } # スパム投稿処理 if ($spam && $mode ne "admin_repost") { # 投稿拒否ログの記録 if ($spamlog) { &write_spamlog; } if ($spamresult) { # エラー表示 if ($spamresult eq '1') { &error("迷惑投稿のため処理を中断しました"); } else { sleep($spamresult); &error("迷惑投稿のため処理を中断しました"); } } elsif ($spammsg) { &message("$spammsg"); } else { &access_error; } } # 記事数調整 @past=(); while ($max <= @file) { $past = pop(@file); unshift(@past,$past) if ($pastkey); } # 過去ログ if (@past > 0) { &past_make(@past); } # ログを更新 $time = time; # 復活処理 if ($mode eq "admin_repost") { $date= $in{'date'}; $host= $in{'host'}; $pwd = $in{'pwd'}; $time = $in{'tim'}; } $no++; unshift (@file,"$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pwd<>$time<>\n"); # 一時ファイルを作成 if (!$logbackup) { $tempfile = $logfile; } open(OUT,">$tempfile") || &error("Write Error : ログファイルに書き込みができません。"); chmod (0606,$tempfile); print OUT @file; close(OUT); # 一時ファイル正常更新時にログファイルにリネーム if ( $logbackup && (-s $tempfile) > 100 ) { rename ($tempfile,$logfile) || &error("Rename Error"); } # ロック解除 &unlock if ($lockkey); # クッキーを発行 if ($mode ne "admin_repost") { if ($no_email == 2) { $in{'email'} =~ s/\@/@/; } &set_cookie($in{'name'},$in{'email'},$in{'url'},$in{'pwd'},); if ($no_email == 2) { $in{'email'} =~ s/@/\@/; } } # メール処理 if ($sendmail && $mail && $in{'email'} ne $mail) { &mailto; } # 完了メッセージ &message("投稿は正常に処理されました"); } #------------------------------------------------- # メッセージ #------------------------------------------------- sub message { local($msg) = @_; &header; print "

\n"; print "

$msg

\n"; print "
\n"; print "
\n"; print "
\n\n"; exit; } #------------------------------------------------- # 留意事項 #------------------------------------------------- sub howto { &header; print <

掲示板利用上の注意

  1. この掲示板はクッキー対応です。1度記事を投稿いただくと、おなまえ、Eメール、URL、暗証キーの情報は2回目以降は自動入力されます。(ただし利用者のブラウザがクッキー対応の場合)
  2. 投稿内容には、タグは一切使用できません。
  3. 記事を投稿する上での必須入力項目は「おなまえ」「メッセージ」です。Eメール、URL、題名、暗証キーは任意です。
  4. 記事には、半角カナは一切使用しないで下さい。文字化けの原因となります。
  5. 記事の投稿時に暗証キー(英数字で8文字以内)を入れておくと、その記事は次回暗証キーによって削除することができます。
  6. 記事の保持件数は最大$max件です。それを超えると古い順に自動削除されます。
  7. 既存の記事に簡単に「返信」することができます。各記事にある「返信」ボタンを押すと投稿フォームが返信用となります。
  8. 過去の投稿記事から「キーワード」によって簡易検索ができます。トップメニューの「ワード検索」のリンクをクリックすると検索モードとなります。
  9. 管理者が著しく不利益と判断する記事や他人を誹謗中傷する記事は予\告なく削除することがあります。
EOM exit; } #------------------------------------------------- # 検索画面 #------------------------------------------------- sub find { &header; print <<"EOM";
  • 検索したいキーワードを入力し、「条件」「表\示」を選択して「検索」ボタンを押して下さい。
  • キーワードは半角スペースで区切って複数指定することができます。
EOM &search("find", $logfile); print "\n"; exit; } #------------------------------------------------- # 検索処理 #------------------------------------------------- sub search { local($md, $target) = @_; local($i, $flag, $next, $back, $enwd, $wd, @wd); print "
\n"; print "\n"; local($para)=''; if ($md eq "past") { print "\n"; $para = "&pastlog=$in{'pastlog'}"; } print "キーワード "; print "条件 表\示 "; print "
\n"; # ワード検索の実行と結果表示 if ($in{'word'} ne "") { # 入力内容を整理 $in{'word'} =~ s/\x81\x40/ /g; @wd = split(/\s+/, $in{'word'}); # ファイルを読み込み print "
\n"; $i=0; open(IN,"$target") || &error("Open Error: $target"); while () { $flag=0; foreach $wd (@wd) { if (index($_,$wd) >= 0) { $flag=1; if ($in{'cond'} eq 'OR') { last; } } else { if ($in{'cond'} eq 'AND') { $flag=0; last; } } } if ($flag) { $i++; if ($i < $page + 1) { next; } if ($i > $page + $in{'view'}) { next; } ($no,$ymd,$nam,$eml,$sub,$com,$url) = split(/<>/); # if ($eml) { $nam="$nam"; } if ($eml) { ($em0,$em1) = split(/\@/,$eml); $em1 =~ s/\./&\#46\;/g; $nam = "\n". "\n"; } if ($url) { $com .= "

$url"; } print "


[$no] $sub "; print "投稿者:$nam 投稿日:$ymd

\n"; print "
$com

\n"; } } close(IN); print "

検索結果:$i
\n"; $next = $page + $in{'view'}; $back = $page - $in{'view'}; $enwd = &url_enc($in{'word'}); if ($back >= 0) { print "[前の$in{'view'}件]\n"; } if ($next < $i) { print "[次の$in{'view'}件]\n"; } print "\n"; exit; } } #------------------------------------------------- # クッキー発行 #------------------------------------------------- sub set_cookie { local(@cook) = @_; local($gmt, $cook, @t, @m, @w); @t = gmtime(time + 60*24*60*60); @m = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); @w = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); # 国際標準時を定義 $gmt = sprintf("%s, %02d-%s-%04d %02d:%02d:%02d GMT", $w[$t[6]], $t[3], $m[$t[4]], $t[5]+1900, $t[2], $t[1], $t[0]); # 保存データをURLエンコード foreach (@cook) { s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg; $cook .= "$_<>"; } # 格納 print "Set-Cookie: LIGHT_BOARD=$cook; expires=$gmt\n"; } #------------------------------------------------- # クッキー取得 #------------------------------------------------- sub get_cookie { local($key, $val, *cook); # クッキーを取得 $cook = $ENV{'HTTP_COOKIE'}; # 該当IDを取り出す foreach ( split(/;/, $cook) ) { ($key, $val) = split(/=/); $key =~ s/\s//g; $cook{$key} = $val; } # データをURLデコードして復元 foreach ( split(/<>/, $cook{'LIGHT_BOARD'}) ) { s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg; push(@cook,$_); } return (@cook); } #------------------------------------------------- # 記事削除 #------------------------------------------------- sub dellog { local($no,$dat,$nam,$eml,$sub,$com,$url,$hos,$pwd,@new); # 入力チェック if (!$post_flag) { &error("不正なアクセスです"); } if ($in{'no'} eq "" || $in{'pwd'} eq "") { &error("記事No又はパスワードが入力されていません"); } # ロック開始 &lock if ($lockkey); # ログを読み込む $flag=0; @new=(); open(IN,"$logfile") || &error("Open Error: $logfile"); while () { ($no,$dat,$nam,$eml,$sub,$com,$url,$hos,$pwd) = split(/<>/); if ($in{'no'} == $no) { if ($pwd eq "") { $flag=2; last; } $check = &decrypt($in{'pwd'}, $pwd); if ($check) { $flag=1; next; } else { $flag=3; last; } } push(@new,$_); } close(IN); if (!$flag) { &error("該当記事が見当たりません"); } elsif ($flag == 2) { &error("パスワードが設定されていません"); } elsif ($flag == 3) { &error("パスワードが違います"); } # ログ更新 open(OUT,">$logfile") || &error("Write Error: $logfile"); print OUT @new; close(OUT); # ロック解除 &unlock if ($lockkey); # 完了メッセージ &header; print <<"EOM";

記事は正常に削除されました

EOM exit; } #------------------------------------------------- # 記事修正 #------------------------------------------------- sub editlog { local($no,$dat,$nam,$eml,$sub,$com,$url,$hos,$pwd,@new); # 入力チェック if ($in{'no'} eq "" || $in{'pwd'} eq "") { &error("記事No又はパスワードが入力されていません"); } # 修正実行 if ($in{'job'} eq "edit2") { # 入力チェック if ($in{'name'} eq "") { &error("名前が入力されていません"); } if ($in{'comment'} eq "") { &error("コメントが入力されていません"); } if ($in{'email'} && $in{'email'} !~ /^[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,5}$/) { &error("Eメールの入力内容が正しくありません"); } if ($in{'url'} eq "http://") { $in{'url'}=""; } if ($in{'sub'} eq "") { $in{'sub'} = "無題"; } # ロック開始 &lock if ($lockkey); # 差し替え @new=(); open(IN,"$logfile") || &error("Open Error: $logfile"); while () { ($no,$dat,$nam,$eml,$sub,$com,$url,$hos,$pwd,$tim) = split(/<>/); if ($in{'no'} == $no) { $_="$no<>$dat<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$hos<>$pwd<>$tim<>\n"; $pwd2 = $pwd; } push(@new,$_); } close(IN); # 認証チェック $check = &decrypt($in{'pwd'}, $pwd2); if (!$check) { &error("パスワードが違います"); } # 更新 open(OUT,">$logfile") || &error("Write Error: $logfile"); print OUT @new; close(OUT); # ロック解除 &unlock if ($lockkey); return; } # 記事抽出 $flag=0; open(IN,"$logfile") || &error("Open Error: $logfile"); while () { ($no,$dat,$nam,$eml,$sub,$com,$url,$hos,$pwd) = split(/<>/); if ($in{'no'} == $no) { $flag=1; last; } } close(IN); if (!$flag) { &error("該当の記事が見つかりません"); } elsif ($pwd eq "") { &error('この記事はパスワードが設定されていないため、修正不可能です'); } $check = &decrypt($in{'pwd'}, $pwd); if (!$check) { &error("パスワードが違います"); } # 修正フォーム &edit_form($no,$dat,$nam,$eml,$sub,$com,$url); } #------------------------------------------------- # メール送信 #------------------------------------------------- sub mailto { local($msub,$mbody,$email,$com); # 記事の改行・タグを復元 $com = $in{'comment'}; $com =~ s/
/\n/g; $com =~ s/<//g; $com =~ s/"/"/g; $com =~ s/&/&/g; # メール本文を定義 $mbody = <<"EOM"; 投稿日時:$date ホスト名:$host ブラウザ:$ENV{'HTTP_USER_AGENT'} 投稿者名:$in{'name'} Eメール:$in{'email'} URL :$in{'url'} タイトル:$in{'sub'} $com EOM # 題名をBASE64化 $msub = &base64("[$title : $no] $in{'sub'}"); # メールアドレスがない場合 if ($in{'email'} eq "") { $email = $mail; } else { $email = $in{'email'}; } open(MAIL,"| $sendmail -t") || &error("メール送信失敗"); print MAIL "To: $mail\n"; print MAIL "From: $email\n"; print MAIL "Subject: $msub\n"; print MAIL "MIME-Version: 1.0\n"; print MAIL "Content-type: text/plain; charset=ISO-2022-JP\n"; print MAIL "Content-Transfer-Encoding: 7bit\n"; print MAIL "X-Mailer: $ver\n\n"; foreach ( split(/\n/, $mbody) ) { &jcode'convert(*_, 'jis', 'sjis'); print MAIL $_, "\n"; } close(MAIL); } #------------------------------------------------- # BASE64変換 #------------------------------------------------- # とほほのWWW入門で公開されているルーチンを参考にしました。 # ( http://tohoho.wakusei.ne.jp/ ) sub base64 { local($sub) = @_; &jcode'convert(*sub, 'jis', 'sjis'); $sub =~ s/\x1b\x28\x42/\x1b\x28\x4a/g; $sub = "=?iso-2022-jp?B?" . &b64enc($sub) . "?="; $sub; } sub b64enc { local($ch)="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; local($x, $y, $z, $i); $x = unpack("B*", $_[0]); for ($i=0; $y=substr($x,$i,6); $i+=6) { $z .= substr($ch, ord(pack("B*", "00" . $y)), 1); if (length($y) == 2) { $z .= "=="; } elsif (length($y) == 4) { $z .= "="; } } $z; } #------------------------------------------------- # パスワード暗号 #------------------------------------------------- sub encrypt { local($inp) = $_[0]; local($salt, $crypt, @char); # 候補文字列を定義 @char = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/'); # 乱数で種を抽出 srand; $salt = $char[int(rand(@char))] . $char[int(rand(@char))]; # 暗号化 $crypt = crypt($inp, $salt) || crypt ($inp, '$1$' . $salt); $crypt; } #------------------------------------------------- # パスワード照合 #------------------------------------------------- sub decrypt { local($inp, $log) = @_; # 種抽出 local($salt) = $log =~ /^\$1\$(.*)\$/ && $1 || substr($log, 0, 2); # 照合 if (crypt($inp, $salt) eq $log || crypt($inp, '$1$' . $salt) eq $log) { return (1); } else { return (0); } } #------------------------------------------------- # 自動リンク #------------------------------------------------- sub auto_link { if ($comment_url) { $_[0] =~ s/http/ttp/g; $_[0] =~ s/([^=^\"]|^)(ttps?\:[\w\.\~\-\/\?\&\=\+\@\;\#\:\%\,]+)/$1h$2<\/a>/g; } else { $_[0] =~ s/([^=^\"]|^)(https?\:[\w\.\~\-\/\?\&\=\+\@\;\#\:\%\,]+)/$1$2<\/a>/g; } } #------------------------------------------------- # URLエンコード #------------------------------------------------- sub url_enc { local($_) = @_; s/(\W)/'%' . unpack('H2', $1)/eg; s/\s/+/g; $_; } #------------------------------------------------- # 過去ログ画面 #------------------------------------------------- sub pastlog { local($no,$i,$file,$next,$back); open(IN,"$pastno") || &error("Open Error: $pastno"); $no = ; close(IN); $in{'pastlog'} =~ s/\D//g; if (!$in{'pastlog'}) { $in{'pastlog'} = $no; } &header; print <<"EOM"; [掲示板に戻る]
\n"; $file = sprintf("%s%04d\.cgi", $pastdir,$in{'pastlog'}); &search("past", $file); print "
\n"; $i=0; open(IN,"$file") || &error("Open Error: $file"); while () { ($no,$dat,$nam,$eml,$sub,$com,$url) = split(/<>/); $i++; if ($i < $page + 1) { next; } if ($i > $page + $plog) { last; } &auto_link($com) if ($link); $com =~ s/([>]|^)(>[^<]*)/$1$2<\/font>/g; # if ($eml) { $nam = "$nam"; } if ($eml) { ($em0,$em1) = split(/\@/,$eml); $em1 =~ s/\./&\#46\;/g; $nam = "\n". "\n"; } if ($url) { $url = "<URL>"; } print "

[$no] $sub "; print "投稿者:$nam 投稿日:$dat   $url

$com

\n"; } close(IN); print "

\n"; $next = $page + $plog; $back = $page - $plog; print "
過去ログ "; print "
\n"; if ($back >= 0) { print "\n"; } if ($next < $i) { print "\n"; } print "
\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "
\n\n"; exit; } #------------------------------------------------- # 過去ログ生成 #------------------------------------------------- sub past_make { local(@past) = @_; local($count,$pastfile,$i,$f,@data); # 過去ログファイル名を定義 open(NO,"$pastno") || &error("Open Error: $pastno"); $count = ; close(NO); $pastfile = sprintf("%s%04d\.cgi", $pastdir,$count); # 過去ログを開く $i=0; $f=0; @data=(); open(IN,"$pastfile") || &error("Open Error: $pastfile"); while () { $i++; push(@data,$_); # 最大件数を超えると中断 if ($i >= $pastmax) { $f++; last; } } close(IN); # 最大件数をオーバーすると次ファイルを自動生成 if ($f) { # カウントファイル更新 $count++; open(NO,">$pastno") || &error("Write Error: $pastno"); print NO $count; close(NO); $pastfile = sprintf("%s%04d\.cgi", $pastdir,$count); @data = @past; } else { unshift(@data,@past); } # 過去ログを更新 open(OUT,">$pastfile") || &error("Write Error: $pastfile"); print OUT @data; close(OUT); if ($f) { chmod(0666, $pastfile); } } #------------------------------------------------- # チェックモード #------------------------------------------------- sub check { &header; print <Check Mode
    EOM # ログチェック foreach ($logfile, $setfile) { if (-e $_) { print "
  • パス:$_ → OK\n"; if (-r $_ && -w $_) { print "
  • パーミッション:$_ → OK\n"; } else { print "パーミッション:$_ → NG\n"; } } else { print "
  • パス:$_ → NG\n"; } } # ロックディレクトリ print "
  • ロック形式:"; if ($lockkey == 0) { print "ロック設定なし\n"; } else { if ($lockkey == 1) { print "symlink\n"; } else { print "mkdir\n"; } ($lockdir) = $lockfile =~ /(.*)[\\\/].*$/; print "
  • ロックディレクトリ:$lockdir\n"; if (-d $lockdir) { print "
  • ロックディレクトリのパス:OK\n"; if (-r $lockdir && -w $lockdir && -x $lockdir) { print "
  • ロックディレクトリのパーミッション:OK\n"; } else { print "
  • ロックディレクトリのパーミッション:NG → $lockdir\n"; } } else { print "
  • ロックディレクトリのパス:NG → $lockdir\n"; } } # 過去ログ @yn = ('なし', 'あり'); print "
  • 過去ログ:$yn[$pastkey]\n"; if ($pastkey) { if (-e $pastno) { print "
  • パス:$pastno → OK\n"; if (-r $pastno && -w $pastno) { print "
  • パーミッション:$pastno → OK\n"; } else { print "
  • パーミッション:$pastno → NG\n"; } } else { print "
  • パス:$pastno → NG\n"; } if (-d $pastdir) { print "
  • パス:$pastdir → OK\n"; if (-r $pastdir && -w $pastdir && -x $pastdir) { print "
  • パーミッション:$pastdir → OK\n"; } else { print "
  • パーミッション:$pastdir → NG\n"; } } else { print "
  • パス:$pastdir → NG\n"; } } print "
\n\n"; exit; } #------------------------------------------------- # スパム拡張オプションチェック #------------------------------------------------- sub option_check { local ($pw,$em,$cm,$ur) = @_; # 暗証キーをチェック local $pwdflag = 0; if ($ng_pass && $pw) { if ($pw =~ /\s/) { $pwdflag = 1; } if ($pw eq reverse($pw)) { $pwdflag = 1; } } if ($pwdflag) { &error("暗証キーが不正です。"); } # メールアドレスをチェック if ($no_email == 1 && $em) { &error("メールアドレスは入力禁止です。"); } if ($no_email == 2 && $em && $em!~ /^[\w\.\-]+@[\w\.\-]+\.[a-zA-Z]{2,6}$/) { &error("アットマーク @ は全角で入力して下さい。"); } # URLの直接書き込みをチェック if ($comment_url) { $urlnum = ($cm =~ s/http/http/ig); if ($urlnum) { &error("URLは先頭のhを抜いて書き込んで下さい。"); } } } #------------------------------------------------- # スパムチェック #------------------------------------------------- sub spam_check{ local ($u2,$bt,$cm,$re,$ur,$em,$sb,$ad,$fc,$cn,$sb2,$sb3,$sb4,$lng,$ua) = @_; $spam = 0; # フォーム投稿からのチェック if ($u2 || $sb2 || $sb3 || $sb4) { $spam=1; $reason = "プログラム投稿(非ブラウザ)"; } if (!$spam) { if (!$bt || !$fc || !$ad) { $spam=1; $reason = "プログラム投稿(非フォーム投稿)"; } } if(!$spam) { if($ipcheckmode) { local $enadr = &encode_addr($addr); if ($ad ne $enadr) { $spam=1; $reason = "プログラム投稿(IP不一致)"; } } } if(!$spam) { if ($em && $em =~ /https?\:\/\//) { $spam=1; $reason = "プログラム投稿(email/URL不正)"; } } if(!$spam) { if ($ur && $ur =~ /^[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,6}$/) { $spam=1; $reason = "プログラム投稿(email/URL不正)"; } } if (!$spam) { if (!$cn || !$cookiecheck) { local $posttime2 = time; local $timecheck2 = $posttime2 - $bt; if ($timecheck2 < 0) { $timecheck2 = 0 - $timecheck2; } if ($maxtime && $timecheck2 > $maxtime) { $spam=1; $reason = "プログラム投稿(投稿まで$timecheck2秒)"; } if ($mintime && $timecheck2 < $mintime) { $spam=1; $reason = "プログラム投稿(投稿まで$timecheck2秒)"; } } } # 日本語環境チェック if (!$spam) { if ($japanese) { if ($lng !~ /ja/i && $ua !~ /ja/i) { $spam=1; $reason = "不正ブラウザ(非日本語環境)"; } } } # スパム投稿チェック(多数URL記述対応) if (!$spam) { $urlnum = ($cm =~ s/http/http/ig); if ($spamurlnum && ($urlnum >= $spamurlnum)) { $spam=1; $reason = "URLの書き込みが$urlnum個"; } } # URL以外の文字数をチェック if(!$spam) { if ($characheck) { if ($cm =~ /(https?\:\/\/[\w\.\~\-\/\?\&\=\;\#\:\%\+\@\,]+)/ || $ur) { local $charamsg = $cm; $charamsg =~ s/(https?\:\/\/[\w\.\~\-\/\?\&\=\;\#\:\%\+\@\,]+)//g; $charamsg =~ s/[\s\n\r\t
]//g; $msgnum = length($charamsg); if ($msgnum < $characheck) { $spam=1; $reason = "コメントの文字数が$msgnumバイトと少ない"; } } } } # 全角文字(日本語)チェック if(!$spam) { if ($asciicheck) { if ($cm !~ /(\x82[\x9F-\xF2])|(\x83[\x40-\x96])/) { $spam=1; $reason = "コメントに日本語(ひらがな/カタカナ)がない"; } } } if(!$spam) { if (-e $spamdata) { if ($spamdatacheck || !$re) { # 禁止URLデータをロード open(SPAM,"$spamdata") || &error("Open Error : $spamdata"); $SPM = ; close(SPAM); # 禁止URLの書き込みをチェック foreach (split(/\,/, $SPM)) { if(length($_) > 1) { if ($cm =~ /\Q$_\E/i) { $spam=1; $reason = "コメント内に禁止語句$_を含む投稿"; last; } if (!$spam && $ur =~ /\Q$_\E/i) { $spam=1; $reason = "URLに禁止語句$_を含む投稿"; last; } if (!$spam && $ngmail && $em =~ /\Q$_\E/i) { $spam=1; $reason = "メールアドレスに禁止語句$_を含む投稿"; last; } if (!$spam && $ngtitle && $sb =~ /\Q$_\E/i) { $spam=1; $reason = "タイトルに禁止語句$_を含む投稿"; last; } } } } } } if(!$spam) { if ($urlcheck) { if ($urlcheck eq 2 || !$re) { # URLのコメントへの重複書き込みをチェック if($ur) { $ur =~ s/\/$//; if ($cm =~ /\Q$ur\E/i) { if ($' !~ /(^\/?[\w\?]+?)/) { $spam=1; $reason = "コメント内にURL欄と同じURLを含む投稿"; } } } } } } # 携帯除外 if(!$keitaicheck && $type ne 'p') { $spam = 0; } return ($spam,$reason); } #------------------------------------------------- # スパムログ記録 #------------------------------------------------- sub write_spamlog { local $num = ($in{'comment'} =~ s/http/http/ig); if($num >= $maxurl) { $in{'comment'} ="メッセージ内のURL数が$maxurl以上のため削除"; } $in{'comment'} =~ s/"/"/g; $times = time; if (!$in{"$bbscheckmode"}) { $in{"$bbscheckmode"} = $times; } push (@spamlog,"$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pwd<>$time<>$reason<>$in{\"$bbscheckmode\"}<>$ENV{'HTTP_REFERER'}<>$ENV{'HTTP_USER_AGENT'}<>$times<>\n"); if (-e $spamlogfile) { open(OUT,">>$spamlogfile") || &error("Write Error"); print OUT @spamlog; close(OUT); } else { open(OUT,">$spamlogfile"); chmod (0606,"$spamlogfile"); print OUT @spamlog; close(OUT); } # 古いスパムログを削除 if ($spamlog_max) { while ((-s $spamlogfile) > $spamlog_maxfile ) { open(IN,"$spamlogfile") || &error("Open Error : >$spamlogfile"); @spamlog = ; close(IN); shift(@spamlog); open(OUT,">$spamlogfile") || &error("Write Error : $spamlogfile"); print OUT @spamlog; close(OUT); } } # ロック解除 &unlock if ($lockkey); } #------------------------------------------------- # スパムログ削除 #------------------------------------------------- sub del_spamlog { local $checktime = shift; $i=0; $flag=0; @newspm = (); open(IN,"$spamlogfile") || &error("Open Error: $spamlogfile"); while () { $i++; local ($no,$date,$name,$email,$sub,$comment,$url,$host,$pwd,$tim, $reason,$fcheck,$referer,$useragent) = split(/<>/); if ($fcheck eq $checktime) { $flag=1; $_ = ""; } else { $_ = "$no<>$date<>$name<>$email<>$sub<>$comment<>$url<>$host<>$pwd<>$tim<>$reason<>$fcheck<>$referer<>$useragent<>\n"; } push(@newspm,"$_"); } close(IN); open(OUT,">$spamlogfile") || &error("Write Error : $spamlogfile"); print OUT @newspm; close(OUT); } #------------------------------------------------- # プレビューチェック #------------------------------------------------- sub previewcheck { $in{"$bbscheckmode"} = &decode_bbsmode($in{"$bbscheckmode"}); if ($mode eq "$writevalue") { if ($keychange) { ($in{'email'},$in{'url'})=($in{'url'},$in{'email'}); } if ($previewtime) { if ($in{'pview'} ne "on") { local $posttime = time; $timecheck = $posttime - $in{"$bbscheckmode"}; if ($timecheck < 0) { $timecheck2 = 0 - $timecheck; } if ($timecheck <= $maxtime) { if ($timecheck > $previewmax) { $mode = "previewmode"; } } if ($timecheck >= $mintime) { if ($timecheck < $previewmin) { $mode = "previewmode"; } } } } } } #------------------------------------------------- # プレビュー画面 #------------------------------------------------- sub previewmode { local $timecheck = shift; $time = time; $date = &get_time($time); if ($in{'pwd'} ne "") { $pwd = &encrypt($in{'pwd'}); } $reason = "プレビューモードトラップ($timecheck秒)"; # プレビューログの記録 if ($spamlog) { &write_spamlog; } $in{"$bbscheckmode"} = &encode_bbsmode($in{"$bbscheckmode"}); &header; print < EOM $in{'name'} =~ s/"/"/g; $in{'sub'} =~ s/"/"/g; $in{'comment'} =~ s/"/"/g; # URL if ($in{'url'} eq "http://") { $in{'url'} = ""; } # 日本語チェック if ($in{'comment'} =~ /(\x82[\x9F-\xF2])/) { $checked0 = "checked"; $checked1 = ""; $in{'url'} =~ s/\/$//; $in{'email'} =~ s/\/$//; # URL重複チェック if ($in{'url'} && $in{'comment'} =~ /\Q$in{'url'}\E/i || $in{'email'} && $in{'comment'} =~ /\Q$in{'email'}\E/i) { if ($' !~ /(^\/?[\w\?]+?)/) { $checked0 = ""; $checked1 = "checked"; } } } else { $checked0 = ""; $checked1 = "checked"; } if ($type eq 'p') { print < ▼ 内容を確認し、"投稿する"をチェックして投稿して下さい。

お名前 $in{'name'}
Eメール $in{'email'}
タイトル $in{'sub'}
参照先 $in{'url'}
メッセージ
$in{'comment'}

投稿する   投稿をやめる
EOM } else { print < おなまえ: $in{'name'}
題名: $in{'sub'}
Eメール: $in{'email'}
コメント
$in{'comment'}


投稿する
投稿をやめる
EOM } exit; } #------------------# # JavaScript無効 # #------------------# sub noscript { &header; print <<"EOM";
JavaScriptを利用したメールアドレス表\示について

スパム(一方的迷惑メール)およびウイルス対策のため、JavaScriptを利用したメールアドレス表\示を採用しています。
お手数をおかけしますが、投稿者のメールアドレスを表\示させるためには、JavaScriptを有効にしてください。



EOM exit; } __END__