#!/usr/local/bin/perl #┌───────────────────────────────── #│ Aska BBS v3.41 (2006/06/20) #│ Copyright (c) KentWeb #│ webmaster@kent-web.com #│ http://www.kent-web.com/ #└───────────────────────────────── $ver = 'ASKA BBS v3.41'; #┌───────────────────────────────── #│ [注意事項] #│ 1. このスクリプトはフリーソフトです。このスクリプトを使用した #│ いかなる損害に対して作者は一切の責任を負いません。 #│ 2. 設置に関する質問はサポート掲示板にお願いいたします。 #│ 直接メールによる質問は一切お受けいたしておりません。 #└───────────────────────────────── # # 【ファイル構成例】 # # public_html (ホームディレクトリ) # | # +-- aska / aska.cgi [705] # | askalog.cgi [606] # | jcode.pl [604] # | # +-- lock [707] / # #------------------------------------------------- # ■基本設定 #------------------------------------------------- # ライブラリ取り込み require './jcode.pl'; # タイトル名 $title = "BBS"; # タイトル文字の色 $tCol = "#666666"; # タイトル文字サイズ $tSize = '24px'; # 本文文字サイズ $bSize = '13px'; # 本文文字スタイル $bFace = '"MS UI Gothic", "MS Pゴシック", Osaka'; # 記事題名の色 $subCol = "#DD0000"; # スクリプトURL $script = './aska.cgi'; # ログファイル $logfile = './askalog.cgi'; # 管理用パスワード $pass = '9968'; # 最大記事数(これを超える記事は古い順に削除) $max = 50; # 戻り先URL $home = "http://holiday.s14.xrea.com/home.html"; # タイトル画像を使う場合 (http://から画像を指定) $ImgT = ""; $ImgW = 300; # 横幅サイズ $ImgH = 70; # 縦幅サイズ # bodyタグ $body = ''; # URLの自動リンク (0=no 1=yes) $autolink = 1; # 引用部色変更 # 1 : 色指定を行うと「引用部」を色変更します # 2 : この機能を使用しない場合は何も記述しないで下さい ($refCol="";) $refCol = "#804000"; # 1ページあたりの記事表示件数 $pageLog = 10; # ファイルロック形式 # → 0=no 1=symlink関数 2=mkdir関数 $lockkey = 1; # ロックファイル名 $lockfile = './lock/aska.lock'; # メール通知機能 # 0 : 通知しない # 1 : 通知する → 自分の投稿記事も通知する # 2 : 通知する → 自分の投稿記事は通知しない $mailing = 0; # メールソフトのパス(メール通知する場合) # → sendmailの例: /usr/lib/sendmail # → blatjの例: c:\www\mail\blatj.exe $mailprog = '/usr/lib/sendmail'; # メール通知先アドレス(メール通知する場合) $mailto = 'xxx@xxx.xxx'; # タグ広告挿入オプション # → の代わりに「広告タグ」を挿入。 # → 広告タグ以外に、MIDIタグ や LimeCounter等のタグにも使用可能。 $banner1 = ''; # 表示部上部に挿入 $banner2 = ''; # 表示部下部に挿入 # 記事の更新は method=post に限定する場合(セキュリティ対策) # → 0=no 1=yes $postonly = 1; # 他サイトから投稿排除時に指定する場合(セキュリティ対策) # → 掲示板のURLをhttp://から書く $baseUrl = ''; # 投稿制限(セキュリティ対策) # 0 : しない # 1 : 同一IPアドレスからの投稿間隔を制限する # 2 : 全ての投稿間隔を制限する $regCtl = 1; # 制限投稿間隔(秒数) # → $regCtl での投稿間隔 $wait = 60; # 禁止ワード # → 投稿時禁止するワードをコンマで区切る $no_wd = ''; # 日本語チェック(投稿時日本語が含まれていなければ拒否する) # 0=No 1=Yes $jp_wd = 0; # URL個数チェック # → 投稿コメント中に含まれるURL個数の最大値 $urlnum = 5; # 投稿後の処理 # → 掲示板自身のURLを記述しておくと、投稿後リロードします # → ブラウザを再読み込みしても二重投稿されない措置。 # → Locationヘッダの使用可能なサーバのみ $location = 'http://holiday.s14.xrea.com/bbs/aska.cgi'; # ホスト取得方法 # 0 : gethostbyaddr関数を使わない # 1 : gethostbyaddr関数を使う $gethostbyaddr = 0; # アクセス制限(半角スペースで区切る、アスタリスク可) # → 拒否ホスト名を記述(後方一致)【例】*.anonymizer.com $deny_host = ''; # → 拒否IPアドレスを記述(前方一致)【例】210.12.345.* $deny_addr = ''; # 1回当りの最大投稿サイズ (bytes) $maxData = 51200; #------------------------------------------------- # ■設定完了 #------------------------------------------------- &decode; &axscheck; if ($mode eq 'regist') { ®ist; } elsif ($mode eq 'find') { &find; } elsif ($mode eq 'howto') { &howto; } elsif ($mode eq 'admin') { &admin; } elsif ($mode eq 'usrdel') { &usrdel; } elsif ($mode eq 'check') { ✓ } &html; #------------------------------------------------- # アクセス制限 #------------------------------------------------- sub axscheck { # IP&ホスト取得 $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($gethostbyaddr && ($host eq "" || $host eq $addr)) { $host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2); } # IPチェック local($flg); foreach ( split(/\s+/, $deny_addr) ) { s/\./\\\./g; s/\*/\.\*/g; if ($addr =~ /^$_/i) { $flg = 1; last; } } if ($flg) { &error("アクセスを許可されていません"); # ホストチェック } elsif ($host) { foreach ( split(/\s+/, $deny_host) ) { s/\./\\\./g; s/\*/\.\*/g; if ($host =~ /$_$/i) { $flg = 1; last; } } if ($flg) { &error("アクセスを許可されていません"); } } if ($host eq "") { $host = $addr; } } #------------------------------------------------- # 記事表示 #------------------------------------------------- sub html { local($r_sub,$r_com); # クッキー取得 local($cnam,$ceml,$curl,$cpwd) = &get_cookie; if (!$curl) { $curl = 'http://'; } # レス処理 $in{'res'} =~ s/\D//g; if ($in{'res'}) { local($flag,$no,$dat,$nam,$eml,$sub,$com); open(IN,"$logfile"); while () { ($no,$dat,$nam,$eml,$sub,$com) = split(/<>/); if ($in{'res'} == $no) { $flag = 1; last; } } close(IN); if (!$flag) { &error("該当記事が見つかりません"); } $sub =~ s/^Re://g; $sub =~ s/\[\d+\]\s?//g; $r_sub = "Re:[$no] $sub"; $r_com = "> $com"; $r_com =~ s/
/\r> /ig; } &header; print "
\n"; print "$banner1

\n" if ($banner1 ne ""); # タイトル if ($ImgT) { print "\"$title\"\n"; } else { print "$title\n"; } print < [トップに戻る] [留意事項] [ワード検索] [管理用]


おなまえ
Eメール
タイトル
メッセージ
参照先
削除キー (英数字で8文字以内)
クッキー情報保存
EOM local($i) = 0; open(IN,"$logfile") || &error("Open Error: $logfile"); while () { $i++; next if ($i < $page + 1); next if ($i > $page + $pageLog); local($no,$dat,$nam,$eml,$sub,$com,$url) = split(/<>/); if ($eml) { $nam = "$nam"; } if ($autolink) { &auto_link($com); } if ($refCol) { $com =~ s/([\>]|^)(>[^<]*)/$1$2<\/font>/g; } print "

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

$com"; print "

$url" if ($url); print "

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


EOM # ページ繰り越し local($next) = $page + $pageLog; local($back) = $page - $pageLog; if ($back >= 0) { print "\n"; } if ($next < $i) { print "\n"; } # 著作権表示(削除禁止) print <
記事No 削除キー
$banner2

- ASKA BBS -

EOM exit; } #------------------------------------------------- # 記事書込 #------------------------------------------------- sub regist { # 投稿チェック if ($postonly && !$post_flag) { &error("不正なアクセスです"); } if ($baseUrl) { &refCheck; } # チェック if ($no_wd) { &no_wd; } if ($jp_wd) { &jp_wd; } if ($urlnum > 0) { &urlnum; } # フォーム内容をチェック local($err); if ($in{'name'} eq "") { $err .= "名前が入力されていません
"; } if ($in{'comment'} eq "") { $err .= "コメントが入力されていません
"; } if ($in{'email'} && $in{'email'}!~ /^[\w\.\-]+\@[\w\.\-]+\.[a-zA-Z]{2,6}$/) { $err .= "Eメールの入力内容が不正です
"; } if ($err) { &error($err); } if ($in{'url'} eq "http://") { $in{'url'} = ""; } if ($in{'sub'} eq "") { $in{'sub'} = "無題"; } # ロック処理 &lock if ($lockkey); # 先頭記事読み取り local($top,$i,$flag,@data); open(DAT,"+< $logfile") || &error("Open Error: $logfile"); $top = ; # 重複投稿チェック local($no,$dat,$nam,$eml,$sub,$com,$url,$hos,$pw,$tim) = split(/<>/, $top); if ($in{'name'} eq $nam && $in{'comment'} eq $com) { close(DAT); &error("二重投稿は禁止です"); } # 連続投稿チェック local($time) = time; if ($regCtl == 1) { if ($host eq $hos && $time - $tim < $wait) { $flag = 1; } } elsif ($regCtl == 2) { if ($time - $tim < $wait) { $flag = 1; } } if ($flag) { close(DAT); &error("現在投稿制限中です。もうしばらくたってから投稿をお願いします"); } # 記事No採番 $no++; # 削除キー暗号化 local($pwd); if ($in{'pwd'} ne "") { $pwd = &encrypt($in{'pwd'}); } # 時間取得 local($min,$hour,$mday,$mon,$year,$wday) = (localtime($time))[1..6]; local(@wk) = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); local($date) = sprintf("%04d/%02d/%02d(%s) %02d:%02d", $year+1900,$mon+1,$mday,$wk[$wday],$hour,$min); # 記事数調整 $data[0] = $top; while () { $i++; push(@data,$_); last if ($i >= $max-1); } # 更新 seek(DAT, 0, 0); print DAT "$no<>$date<>$in{'name'}<>$in{'email'}<>$in{'sub'}<>$in{'comment'}<>$in{'url'}<>$host<>$pwd<>$time<>\n"; print DAT @data; truncate(DAT, tell(DAT)); close(DAT); # ロック解除 &unlock if ($lockkey); # クッキーを記憶 if ($in{'cook'} eq 'on') { &set_cookie($in{'name'},$in{'email'},$in{'url'},$in{'pwd'}); } # メール通知処理 if ($mailing == 1 || ($mailing == 2 && $in{'email'} ne $mailto)) { &mail_to; } # リロード if ($location) { if ($ENV{'PERLXS'} eq "PerlIS") { print "HTTP/1.0 302 Temporary Redirection\r\n"; print "Content-type: text/html\n"; } print "Location: $location?\n\n"; exit; } else { &message("投稿は正常に受理されました"); } } #------------------------------------------------- # ワード検索 #------------------------------------------------- sub find { &header; print <
  • キーワードを入力し、検索ボタンを押してください。
  • キーワードはスペースで区切って複数指定することができます。
    キーワード 条件 表\示
EOM # ワード検索の実行と結果表示 if ($in{'word'} ne "") { # 入力内容を整理 $in{'word'} =~ s/\x81\x40/ /g; local(@wd) = split(/\s+/, $in{'word'}); # 検索 print "
\n"; local($i) = 0; local(@find); open(IN,"$logfile") || &error("Open Error: $logfile"); while () { local($no,$dat,$nam,$eml,$sub,$com,$url) = split(/<>/); $flag = 0; foreach $wd (@wd) { if (index("$no $nam $eml $sub $com $url",$wd) >= 0) { $flag = 1; if ($in{'cond'} eq 'OR') { last; } } else { if ($in{'cond'} eq 'AND') { $flag = 0; last; } } } if ($flag) { $i++; next if ($i < $page + 1); next if ($i > $page + $in{'view'}); push(@find,$_); } } close(IN); print "
$in{'word'} に関連する記事は$i件見つかりました。\n"; foreach (@find) { local($no,$ymd,$nam,$eml,$sub,$com,$url) = split(/<>/); if ($eml) { $nam="$nam"; } if ($url) { $com .= "

$url"; } print "


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

\n"; print "
$com

\n"; } print "

\n"; $next = $page + $in{'view'}; $back = $page - $in{'view'}; if ($back >= 0) { print "\n"; } if ($next < $i) { print "\n"; } } print < EOM exit; } #------------------------------------------------- # 管理モード #------------------------------------------------- sub admin { # 認証 if ($in{'pass'} eq "") { &enter; } elsif ($in{'pass'} ne $pass) { &error("パスワードが違います"); } # 削除処理 if ($in{'job'} eq "dele" && $in{'no'}) { # 削除情報 local(@del) = split(/\0/, $in{'no'}); # ロック開始 &lock if ($lockkey); # 削除情報をマッチング local(@data); open(DAT,"+< $logfile") || &error("Open Error: $logfile"); while () { local($no) = split(/<>/); local($flag); foreach $del (@del) { if ($no == $del) { $flag = 1; last; } } if (!$flag) { push(@data,$_); } } # 更新 truncate(DAT, 0); seek(DAT, 0, 0); print DAT @data; close(DAT); # ロック解除 &unlock if ($lockkey); # 修正画面 } elsif ($in{'job'} eq "edit" && $in{'no'}) { if ($in{'no'} =~ /\0/) { &error("修正の場合選択する記事は1つのみです"); } # 記事抽出 local($no,$dat,$nam,$eml,$sub,$com,$url); open(IN,"$logfile") || &error("Open Error: $logfile"); while () { ($no,$dat,$nam,$eml,$sub,$com,$url) = split(/<>/); if ($in{'no'} == $no) { last; } } close(IN); # 修正フォームへ &edit_form($no,$dat,$nam,$eml,$sub,$com,$url); # 修正実行 } elsif ($in{'job'} eq "edit2") { if ($in{'url'} eq "http://") { $in{'url'} = ""; } if ($in{'sub'} eq "") { $in{'sub'} = "無題"; } # ロック開始 &lock if ($lockkey); # 読み出し local(@data); open(DAT,"+< $logfile") || &error("Open Error: $logfile"); while () { local($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"; } push(@data,$_); } # 更新 truncate(DAT, 0); seek(DAT, 0, 0); print DAT @data; close(DAT); # ロック解除 &unlock if ($lockkey); # 完了メッセージ &message("記事を修正しました"); } # 削除画面を表示 &header; print <
  • 処理を選択して送信ボタンを押してください。
処理:
EOM # 記事を展開 open(IN,"$logfile") || &error("Open Error: $logfile"); while () { local($no,$dat,$nam,$eml,$sub,$com,$url,$hos) = split(/<>/); if ($eml) { $nam="$nam"; } $com =~ s/<[^>]*(>|$)//g; if (length($com) > 60) { $com = substr($com,0,60) . '...'; } print "

"; print "[$no] $sub "; print "$nam - $dat 【$hos】\n"; print "
$com\n"; } close(IN); print <
EOM exit; } #------------------------------------------------- # 修正フォーム #------------------------------------------------- sub edit_form { $com =~ s/
/\n/g; if (!$url) { $url = "http://"; } &header; print <
  • 変更する部分のみ修正して送信ボタンを押してください。
おなまえ
Eメール
タイトル
参照先
メッセージ

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

留意事項

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

  2. 投稿記事には、タグは一切使用できません。

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

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

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

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

  7. 既存の記事に簡単に「返信」することができます。各記事にある「返信」のリンク部を押すと投稿フォームが返信用となります。

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

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

EOM exit; } #------------------------------------------------- # ユーザ記事削除 #------------------------------------------------- sub usrdel { # 投稿チェック if ($postonly && !$post_flag) { &error("不正なアクセスです"); } if ($baseUrl) { &refCheck; } if ($in{'no'} eq '' || $in{'pwd'} eq '') { &error("削除Noまたは削除キーが入力モレです"); } # ロック開始 &lock if ($lockkey); local($flag,$match,@data); open(DAT,"+< $logfile") || &error("Open Error: $logfile"); while () { local($no,$dat,$nam,$eml,$sub,$com,$url,$hos,$pw) = split(/<>/); if ($in{'no'} == $no) { $flag = 1; if (!$pw) { $flag = 2; last; } $match = &decrypt($in{'pwd'}, $pw); next; } push(@data,$_); } # 判定 if ($flag == 2) { &error("削除キーが設定されていません"); } elsif (!$flag) { &error("該当記事が見当たりません"); } elsif ($match != 1) { &error("削除キーが違います"); } # ログを更新 truncate(DAT, 0); seek(DAT, 0, 0); print DAT @data; close(DAT); # ロック解除 &unlock if ($lockkey); # 完了メッセージ &message("記事を削除しました"); } #------------------------------------------------- # フォームデコード #------------------------------------------------- sub decode { local($buf); if ($ENV{'REQUEST_METHOD'} eq "POST") { $post_flag = 1; if ($ENV{'CONTENT_LENGTH'} > $maxData) { &error("投稿量が大きすぎます"); } read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $post_flag = 0; $buf = $ENV{'QUERY_STRING'}; } undef(%in); $page = 0; foreach ( split(/&/, $buf) ) { local($key, $val) = split(/=/); $val =~ tr/+/ /; $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; # S-JISコード変換 &jcode'convert(*val, "sjis", "", "z"); # エスケープ $val =~ s/&/&/g; $val =~ s/"/"/g; $val =~ s//>/g; $val =~ s/\r\n/
/g; $val =~ s/\r/
/g; $val =~ s/\n/
/g; # ページ繰り越し if ($key =~ /^page(\d+)$/) { $page = $1; } $in{$key} .= "\0" if (defined($in{$key})); $in{$key} .= $val; } $mode = $in{'mode'}; # タイムゾーン設定 $ENV{'TZ'} = "JST-9"; $lockflag = 0; $headflag = 0; } #------------------------------------------------- # HTMLヘッダ #------------------------------------------------- sub header { if ($headflag) { return; } print "Content-type: text/html\n\n"; print <<"EOM"; $title $body EOM $headflag = 1; } #------------------------------------------------- # エラー処理 #------------------------------------------------- sub error { if ($lockflag) { &unlock; } &header; print <

ERROR !

$_[0]

EOM 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: ASKA_BBS=$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{'ASKA_BBS'}) ) { s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg; push(@cook,$_); } return (@cook); } #------------------------------------------------- # crypt暗号 #------------------------------------------------- sub encrypt { local($in) = @_; local($salt, $enc, @s); @s = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/'); srand; $salt = $s[int(rand(@s))] . $s[int(rand(@s))]; $enc = crypt($in, $salt) || crypt ($in, '$1$' . $salt); $enc; } #------------------------------------------------- # crypt照合 #------------------------------------------------- sub decrypt { local($in, $dec) = @_; local($salt) = $dec =~ /^\$1\$(.*)\$/ && $1 || substr($dec, 0, 2); if (crypt($in, $salt) eq $dec || crypt($in, '$1$' . $salt) eq $dec) { return (1); } else { return (0); } } #------------------------------------------------- # ロック処理 #------------------------------------------------- sub lock { # リトライ回数定義 local($retry) = 5; # 古いロックは削除 if (-e $lockfile) { local($mtime) = (stat($lockfile))[9]; if ($mtime < time - 30) { &unlock; } } # symlink関数式ロック if ($lockkey == 1) { while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &error('LOCK is BUSY'); } sleep(1); } # mkdir関数式ロック } elsif ($lockkey == 2) { while (!mkdir($lockfile, 0755)) { if (--$retry <= 0) { &error('LOCK is BUSY'); } sleep(1); } } $lockflag = 1; } #------------------------------------------------- # ロック解除 #------------------------------------------------- sub unlock { if ($lockkey == 1) { unlink($lockfile); } elsif ($lockkey == 2) { rmdir($lockfile); } $lockflag = 0; } #------------------------------------------------- # メール送信 #------------------------------------------------- sub mail_to { local($msub,$mbody,$mcom,$email,$ptype); # メールプログラムのパスチェック unless (-e $mailprog) { &error("メールプログラムのパスが不正です"); } if ($mailprog =~ /blat/i) { $ptype=2; } else { $ptype=1; } # メールタイトルを定義 $msub = "[$title : $no] $in{'sub'}"; # 本文の改行・タグを復元 $mcom = $in{'comment'}; $mcom =~ s/
/\n/g; $mcom =~ s/</</g; $mcom =~ s/>/>/g; $mcom =~ s/"/”/g; $mcom =~ s/&/&/g; $mbody = "$titleに以下の投稿がありました。\n\n"; $mbody .= "Date : $date\n"; $mbody .= "Host : $host\n"; $mbody .= "Agent: $ENV{'HTTP_USER_AGENT'}\n\n"; $mbody .= "名前 : $in{'name'}\n"; $mbody .= "email: $in{'email'}\n"; $mbody .= "題名 : $in{'sub'}\n"; $mbody .= "参照 : $in{'url'}\n" if ($in{'url'}); $mbody .= "\n$mcom\n"; # BlatJ送信 if ($ptype == 2) { # 一時ファイル書き出し local($tempfile) = "./$$\.tmp"; open(TMP,">$tempfile") || &error("Write Error: $tempfile"); print TMP $mbody; close(TMP); # 送信処理 open(MAIL,"| $mailprog $tempfile -t $mailto -s \"$msub\" -q") || &error("送信失敗"); close(MAIL); # 一時ファイル削除 unlink($tempfile); # sendmail送信 } else { # 題名をBASE64化 $msub = &base64($msub); # メールアドレスがない場合は管理者アドレスに置き換え if ($in{'email'} eq "") { $email = $mailto; } else { $email = $in{'email'}; } # sendmail送信 open(MAIL,"| $mailprog -t -i") || &error("メール送信失敗"); print MAIL "To: $mailto\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); } } #------------------------------------------------- # 自動リンク #------------------------------------------------- sub auto_link { $_[0] =~ s/([^=^\"]|^)(https?\:[\w\.\~\-\/\?\&\=\@\;\#\:\%]+)/$1$2<\/a>/g; } #------------------------------------------------- # REFチェック #------------------------------------------------- sub refCheck { local($ref) = $ENV{'HTTP_REFERER'}; $ref =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg; $baseUrl =~ s/(\W)/\\$1/g; if ($ref && $ref !~ /$baseUrl/i) { &error("不正なアクセスです"); } } #------------------------------------------------- # 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 enter { &header; print <

パスワードを入力して下さい

EOM exit; } #------------------------------------------------- # メッセージ表示 #------------------------------------------------- sub message { &header; print < $_[0]

EOM if ($in{'pass'} ne "") { print "\n"; print "\n"; } print < EOM exit; } #------------------------------------------------- # 禁止ワードチェック #------------------------------------------------- sub no_wd { local($flg); foreach ( split(/,/, $no_wd) ) { if (index("$in{'name'} $in{'sub'} $in{'comment'}",$_) >= 0) { $flg = 1; last; } } if ($flg) { &error("禁止ワードが含まれています"); } } #------------------------------------------------- # 日本語チェック #------------------------------------------------- sub jp_wd { local($sub, $com, $mat1, $mat2, $code1, $code2); $sub = $in{'sub'}; $com = $in{'comment'}; if ($sub) { ($mat1, $code1) = &jcode'getcode(*sub); } ($mat2, $code2) = &jcode'getcode(*com); if ($code1 ne 'sjis' && $code2 ne 'sjis') { &error("題名又はコメントに日本語が含まれていません"); } } #------------------------------------------------- # URL個数チェック #------------------------------------------------- sub urlnum { local($com) = $in{'comment'}; local($num) = ($com =~ s|(https?://)|$1|ig); if ($num > $urlnum) { &error("コメント中のURLアドレスは最大$urlnum個までです"); } } #------------------------------------------------- # チェックモード #------------------------------------------------- sub check { &header; print <Check Mode
    EOM # ログファイル if (-e $logfile) { print "
  • LOGパス:OK\n"; if (-r $logfile && -w $logfile) { print "
  • LOGパーミッション:OK\n"; } else { print "
  • LOGパーミッションが不正です。\n"; } } else { print "
  • LOGのパスが不正です:NG → $logfile\n"; } # ロックディレクトリ print "
  • LOCK形式:"; if ($lockkey == 0) { print "LOCK設定なし\n"; } else { if ($lockkey == 1) { print "symlink\n"; } else { print "mkdir\n"; } local($lockdir) = $lockfile =~ /(.*)[\\\/].*$/; print "
  • LOCK DIR:$lockdir\n"; if (-d $lockdir) { print "
  • LOCK DIRパス:OK\n"; if (-r $lockdir && -w $lockdir && -x $lockdir) { print "
  • LOCK DIRパーミッション:OK\n"; } else { print "
  • LOCK DIRパーミッション:NG → $lockdir\n"; } } else { print "
  • LOCK DIRパス:NG → $lockdir\n"; } } print < EOM exit; } __END__