#!/usr/local/bin/perl5 # MAG BOARD v1.1 (2002/05) # Copyright(C) Kent Web 2002 # webmaster@kent-web.com # http://www.kent-web.com/ $ver = 'MagBoard v1.1'; #---------------------------------------------------------------# # [ 注意事項 ] # # ・このスクリプトを使用したいかなる損害も作者は一切の責任を # # 負いません。 # # ・掲示板下部にある「著作権表示」は、削除・改変を行なうことは # # できません。 # #---------------------------------------------------------------# #============# # 基本設定 # #============# # ライブラリ取り込み require './jcode.pl'; # スクリプト # → 絶対パスなら http://から記述 $script = "./magbbs.cgi"; # ログファイル # → 絶対パスなら / から始まるサーバパスで記述 $logfile = "./magbbs.log"; # 設定ファイル # → 絶対パスなら / から始まるサーバパスで記述 $setfile = "./magbbs.ini"; # 会員ファイル # → 絶対パスなら / から始まるサーバパスで記述 $memfile = "./magdata.cgi"; # 管理パスワード $pass = 'clip'; # method形式 (POST/GET) $method = 'POST'; # ホスト名取得方式 # 0 : $ENV{'REMOTE_HOST'}変数で取得 # 1 : gethostbyaddr関数で取得 $gethostbyaddr = 0; # ファイルロック形式 # 0 : no # 1 : yes # → 設定する場合は、ロックファイルを生成するディレクトリ # のパーミッションは原則として「777」に設定する。 $lockkey = 1; # ロックファイル $lockfile = "./lock/magbbs.lock"; # sendmailパス $sendmail = '/usr/lib/sendmail'; #============# # 設定完了 # #============# &decode; &set_file; if ($mode eq "regist") { ®ist; } elsif ($mode eq "form") { &form; } elsif ($mode eq "log_mente") { &log_mente; } elsif ($mode eq "mem_mente") { &mem_mente; } elsif ($mode eq "member") { &member; } elsif ($mode eq "join_in") { &join_in; } elsif ($mode eq "join_out") { &join_out; } elsif ($mode eq "howto") { &howto; } elsif ($mode eq "find") { &find; } elsif ($mode eq "mente_form") { &mente_form; } elsif ($mode eq "edit") { &edit; } &html; #--------------------# # 設定ファイル認識 # #--------------------# sub set_file { open(IN,"$setfile") || &error("Open Error : $setfile"); $data = ; close(IN); ($title,$t_color,$t_size,$ImgT,$bg,$bc,$tx,$lk,$vl,$al,$face,$b_size,$color1,$color2,$color3,$max,$mem_max,$home,$p_log,$deny,$mailto,$sub_message,$mail_head,$signature) = split(/<>/, $data); # アクセス制限 &get_host; local($flag)=0; @deny = split(/\s+/, $deny); foreach (@deny) { $_ =~ s/\*/\.\*/g; if ($host =~ /$_/i) { $flag=1; last; } } if ($flag) { &error("アクセスを許可されていません"); } # ポイント数 $t_size .= 'pt'; $s_size = ($b_size - 1) . 'pt'; $b_size .= 'pt'; } #------------# # 記事表示 # #------------# sub html { open(IN,"$logfile") || &error("Open Error : $logfile"); @lines = ; close(IN); &header; print <<"EOM";

EOM # タイトル部 if ($ImgT) { print "\"$title\"\n"; } else { print "$title\n"; } print "
$sub_message
\n"; # ページログ表示調整 if ($in{'page'} eq "") { $in{'page'} = 0; } $start = $in{'page'}; $end = $in{'page'} + $p_log - 1; if ($#lines < $end) { $end = $#lines; } foreach ($start .. $end) { ($no,$date,$sub,$msg,$url,$img) = split(/<>/, $lines[$_]); # URLリンク &auto_link($msg); print "
\n"; print "
  "; print "$sub
\n"; print "    Date : $date
\n"; print "
$msg\n"; if ($url) { print "

$url\n"; } print "

\n"; } $next_page = $in{'page'} + $p_log; $back_page = $in{'page'} - $p_log; print "


\n"; if ($back_page >= 0) { print "\n"; } if ($next_page < $#lines) { print "\n"; } print "\n"; print "
\n"; print "\n"; print "
\n"; print "\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; print "- Mag Board -\n"; print "
\n"; print "\n"; exit; } #----------------# # 記事投稿処理 # #----------------# sub regist { if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); } &get_time; open(IN,"$logfile") || &error("Open Error : $logfile"); @lines = ; close(IN); ($no,$dmy) = split(/<>/, $lines[0]); $no++; while ($max-1 < @lines) { pop(@lines); } unshift(@lines,"$no<>$in{'date'}<>$in{'sub'}<>$in{'message'}<>$in{'url'}<>$img_key<>\n"); open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @lines; close(OUT); $mail_head =~ s/\r/\n/g; $signature =~ s/\r/\n/g; $mail_body .= "$mail_head\n\n---\n"; $mail_body .= "送信日 : $Date\n"; $mail_body .= "題 名 : $in{'sub'}\n"; $mail_body .= "リンク : $in{'url'}\n" if ($in{'url'}); $mail_body .= "\n$in{'message'}\n\n$signature"; # メール用題名を定義 $mail_sub = $in{'sub'}; # メール本文の改行処理 $mail_body =~ s/
/\n/g; # メール本文/題名を JISコード変換 &jcode'convert(*mail_body,'jis'); &jcode'convert(*mail_sub,'jis'); # バッファをフラッシュ:メール送信に備える $|=1; # メール送信 open(IN,"$memfile") || &error("Open Error : $memfile"); while () { ($num,$date,$email,$ip) = split(/<>/); &SendMail("$email", "$mailto"); } close(IN); } #------------------# # メール送信処理 # #------------------# sub SendMail { local($to, $from) = @_; open(MAIL,"| $sendmail -t") || &error("メール送信に失敗しました"); print MAIL "To: $to\n"; print MAIL "Bcc: $bcc\n" if ($bcc); print MAIL "Errors-To: $mailto\n"; print MAIL "From: $from\n"; print MAIL "Subject: $mail_sub\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"; print MAIL "$mail_body\n"; close(MAIL); } #----------------# # 投稿フォーム # #----------------# sub form { if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); } &get_time; &header; print <<"EOM"; [もどる]

  • 必要事項を記入し「投稿する」を押して下さい
    投稿日
    タイトル
    URL
    メッセージ
    EOM exit; } #--------------------# # 管理者ログメンテ # #--------------------# sub log_mente { if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); } open(IN,"$logfile") || &error("Open Error : $logfile"); @lines = ; close(IN); # 削除処理 if ($in{'action'} eq "delete") { $flag=1; @new=(); foreach (@lines) { ($no,$dmy) = split(/<>/); if ($in{'no'} eq "$no") { $flag=1; } else { push(@new,$_); } } if (!$flag) { &error("削除記事が見つかりません"); } open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); @lines = @new; } &header; print <<"EOM"; [戻る]
    管理モード

    EOM foreach (@lines) { ($no,$date,$sub,$msg,$url,$img) = split(/<>/); $msg =~ s/
    //g; if (length($msg) > 50) { $msg=substr($msg,0,48); $msg .= '..'; } print "\n"; print "\n"; print "\n"; } print "
    削除題名投稿日コメントログ修正
    $sub$date$msg
    \n"; print "\n"; exit; } #------------------------# # 管理者会員情報メンテ # #------------------------# sub mem_mente { if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); } open(IN,"$memfile") || &error("Open Error : $memfile"); @lines = ; close(IN); if ($DEL[0]) { @new=(); foreach (@lines) { ($no,$email) = split(/<>/); $flag=0; foreach $x (@DEL) { if ($no == $x) { $flag=1; last; } } if (!$flag) { push(@new,$_); } } open(OUT,">$memfile") || &error("Write Error : $memfile"); print OUT @new; close(OUT); @lines = @new; } $total = @lines; &header; print <<"EOM"; [戻る]
    管理モード

    アドレス検索:
    EOM # 検索処理 if ($in{'word'}) { print "
    \n"; print "
    \n"; print "\n"; print "\n"; print ""; print "\n

    \n"; open(IN,"$memfile") || &error("Write Error : $memfile"); while () { if ($_ =~ /$in{'word'}/i) { ($num,$date,$email,$ip) = split(/<>/); print "

    \n"; print "$email [$ip]\n"; } } close(IN); print "
    \n"; print "
    \n"; print "\n"; exit; } print <<"EOM";
    登録件数:$total

      EOM foreach (@lines) { ($num,$date,$email,$ip) = split(/<>/); print "

    1. $email [$ip]\n"; } print "
    \n\n"; print "\n"; exit; } #------------------# # メンテフォーム # #------------------# sub mente_form { if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); } open(IN,"$logfile") || &error("Open Error : $logfile"); @lines = ; close(IN); # メンテ処理 if ($in{'action'} eq "retouch") { @new=(); foreach (@lines) { ($no,$date,$sub,$msg,$url,$img) = split(/<>/); if ($in{'no'} eq "$no") { $_ = "$no<>$date<>$in{'sub'}<>$in{'message'}<>$in{'url'}<>$img<>\n"; } push(@new,$_); } open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @new; close(OUT); &html; } foreach (@lines) { ($no,$date,$sub,$msg,$url,$img) = split(/<>/); if ($in{'no'} eq "$no") { last; } } if ($url eq "") { $url = "http://"; } $msg =~ s/
    /\r/g; &header; print <<"EOM";

    以下のフォームから記事の修正を行います

    タイトル
    URL
    コメント
    EOM exit; } #--------------------------# # メール登録・解除画面 # #--------------------------# sub member { open(IN,"$memfile") || &error("Open Error : $memfile"); @lines = ; close(IN); &header; print <<"EOM"; [戻る]
    メールアドレス登録・解除

    講読の登録・解除・変更

    ▼メールマガジンの「登録」

    EOM # 登録件数をチェック if (@lines >= $mem_max) { print "- 現在メールアドレスの登録はできません -\n"; } else { print "

    \n"; print "\n"; print "メールアドレス(半角):
    \n"; print "\n"; print "
    \n"; } print <<"EOM";

    ▼メールマガジンの「解除」

    メールアドレス(半角):



    *1 : 登録したアドレスを「変更」する場合は、一旦「解除」した後、新規に「登録」して下さい。
    *2 : セキュリティ上、同一ホストからの連続登録はできません。
    EOM exit; } #----------------# # メール登録 # #----------------# sub join_in { if ($in{'email'} =~ /\,/) { &error("メールアドレスにコンマが含まれています"); } if ($in{'email'} !~ /(.+)\@(.+)\.(.+)/) { &error("メールアドレスの入力が不正です"); } # 小文字に統一 $in{'email'} =~ tr/[A-Z]/[a-z]/; # ロック開始 if ($lockkey) { &lock; } # 会員ファイルを読み込み open(IN,"$memfile") || &error("Open Error : $memfile"); @lines = ; close(IN); # 登録件数をチェック if (@lines >= $mem_max) { &error("現在登録受付を中止しています"); } # ホスト名を取得 &get_host; # ホストチェック ($num,$date,$email,$ip) = split(/<>/, $lines[0]); if ($host eq "$ip") { &error("同一ホストからの連続投稿はできません"); } # 二重登録をチェック $flag=0; foreach (@lines) { ($no,$date,$email,$ip) = split(/<>/); if ($in{'email'} eq "$email") { $flag=1; last; } } if ($flag) { &error("ご指定のメールアドレスは既に登録済です"); } # 会員Noを採番し、時間を取得 $num++; &get_time('join'); # 改行コード処理 $mail_head =~ s/\r/\n/g; $signature =~ s/\r/\n/g; # メール送信 $mail_body = <<"EOM"; $mail_head --- $title へメールアドレスの登録をありがとうございます。 内容をご確認下さい。 ■送信日時:$Date ■ホスト名:$ENV{'REMOTE_HOST'} ■ブラウザ:$ENV{'HTTP_USER_AGENT'} ■登録メールアドレス:$in{'email'} $signature EOM $mail_sub = "メールマガジン登録のご確認"; # メール本文/題名を JISコード変換 &jcode'convert(*mail_body,'jis'); &jcode'convert(*mail_sub,'jis'); &SendMail("$in{'email'}", "$mailto"); # ファイル更新 unshift(@lines,"$num<>$Date<>$in{'email'}<>$host<>\n"); open(OUT,">$memfile") || &error("Write Error : $memfile"); print OUT @lines; close(OUT); # ロック解除 if ($lockkey) { &unlock; } # 完了メッセージ &header; print <<"EOM";

    登録は正常に終了しました

    登録されたアドレス:$in{'email'}

    [トップに戻る]


    EOM exit; } #----------------# # メール解除 # #----------------# sub join_out { if ($in{'email'} !~ /(.+)\@(.+)\.(.+)/) { &error("メールアドレスの入力が不正です"); } # ロック開始 if ($lockkey) { &lock; } # 会員ファイルを読み込み open(IN,"$memfile") || &error("Open Error : $memfile"); @lines = ; close(IN); # ファイルから該当メールをマッチングし排除 $flag=0; @new=(); foreach (@lines) { ($no,$date,$email,$ip) = split(/<>/); if ($in{'email'} eq "$email") { $flag=1; } else { push(@new,$_); } } if (!$flag) { &error("ご指定のメールアドレスは見当たりませんでした"); } # ファイル更新 open(OUT,">$memfile") || &error("Write Error : $memfile"); print OUT @new; close(OUT); # ロック解除 if ($lockkey) { &unlock; } # 完了メッセージ &header; print <<"EOM";

    解除は正常に終了しました

    解除されたアドレス:$in{'email'}

    [トップに戻る]


    EOM exit; } #------------------# # キーワード検索 # #------------------# sub find { &header; print <<"EOM"; [戻る]
    キーワード検索

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

    キーワード
    検索条件 AND OR
    EOM # ワード検索の実行と結果表示 if ($in{'word'}) { # 入力内容を整理 $cond = $in{'cond'}; $word = $in{'word'}; $word =~ s/ / /g; @pairs = split(/\s+/, $word); # 検索処理 print "
      \n"; open(IN,"$logfile") || &error("Open Error : $logfile"); $i=0; while ($_ = ) { $flag = 0; foreach $pair (@pairs) { if (index($_,$pair) >= 0) { $flag=1; if ($cond eq 'or') { last; } } else { if ($cond eq 'and') { $flag=0; last; } } } if ($flag == 0) { next; } # 結果を表示 $i++; ($no,$date,$sub,$msg,$url,$img) = split(/<>/); if ($url) { $url = "$url"; } print "
    1. $sub
      \n"; print "  Date:$date
      \n"; print "
      $msg

      $url

      \n"; } close(IN); print "
      検索結果は $i件です。\n"; print "
    \n"; } print "\n"; exit; } #----------------# # 利用規定画面 # #----------------# sub howto { &header; print <<"EOM"; [戻る]
    利用方法


    1. この掲示板は「メールマガジン」対応です。

    2. メールアドレスを登録しておくと、この掲示板に更新があると自動でメール通知します。

    3. メールアドレスの登録・解除・変更専用画面 から自由に行なうことができます。

    4. 過去の記事($max件)は 検索画面 からキーワード検索することができます。
    EOM exit; } #--------------------# # 設定ファイル編集 # #--------------------# sub edit { if ($in{'pass'} ne "$pass") { &error("パスワードが違います"); } # 実行 if ($in{'action'} eq "edit") { if ($in{'ImgT'} eq "http://") { $in{'ImgT'} = ""; } if ($in{'bg'} eq "http://") { $in{'bg'} = ""; } if ($in{'mailto'} ne "") { if ($in{'mailto'} =~ /\,/) { &error("メールアドレスに「コンマ」が含まれています"); } if ($in{'mailto'} !~ /.+\@.+\..+/) { &error("メールアドレスの入力が不正です"); } } $in{'deny'} =~ s/ / /g; $in{'sub_message'} =~ s/<//g; $in{'mail_head'} =~ s/<//g; $in{'signature'} =~ s/<//g; open(OUT,">$setfile") || &error("Write Error : $setfile"); print OUT "$in{'title'}<>$in{'t_color'}<>$in{'t_size'}<>$in{'ImgT'}<>$in{'bg'}<>$in{'bc'}<>$in{'tx'}<>$in{'lk'}<>$in{'vl'}<>$in{'al'}<>$in{'face'}<>$in{'b_size'}<>$in{'color1'}<>$in{'color2'}<>$in{'color3'}<>$in{'max'}<>$in{'mem_max'}<>$in{'home'}<>$in{'p_log'}<>$in{'deny'}<>$in{'mailto'}<>$in{'sub_message'}<>$in{'mail_head'}<>$in{'signature'}<>"; close(OUT); # 完了メッセージ &header; print "

    修正は正常に完了しました

    \n"; print "
    \n"; print "
    \n"; print "
    \n\n"; exit; } $t_size =~s /pt$//g; $b_size2 = $b_size; $b_size2 =~s /pt$//g; if ($ImgT eq "") { $ImgT = "http://"; } if ($bg eq "") { $bg = "http://"; } &header; print <<"EOM"; [戻る]
    設定ファイル編集

    - 変更する部分のみ修正してください -


    タイトル名
    タイトル色
    タイトルサイズ ポイント
    タイトル画像 (任意)

    壁紙 (任意)
    背景色
    文字色
    リンク色1  (未訪問)
    リンク色2  (訪問済)
    リンク色3  (訪問中)

    文字サイズ ポイント
    文字タイプ
    題名部色1 (下地の色)
    題名部色2 (■の色)
    題名部色3 (題名文字の色)

    最大記事数
    最大会員数 (これを超えると会員登録を休止します)
    ページ記事数
    戻り先

    アクセス制限
    ・アクセス拒否するホスト名を記述
    ・半角スペースで区切って複数指定可
    ・ワイルドカード (*) 使用可

    管理者E-mail

    一口コメント(タイトル下に表\示)
    メールヘッダ(配信メールの本文先頭に付加)
    メール署名(配信メールの本文末尾に付加)

    EOM exit; } #----------------# # デコード処理 # #----------------# sub decode { if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # S-JISコード変換 &jcode'convert(*value,'sjis'); # タグ処理 $value =~ s//>/g; # 改行処理 if ($name eq "message") { $value =~ s/\r\n/
    /g; $value =~ s/\r/
    /g; $value =~ s/\n/
    /g; } elsif ($name eq "sub_message" || $name eq "mail_head" || $name eq "signature") { $value =~ s/\r\n/\r/g; $value =~ s/\n/\r/g; } else { $value =~ s/\r//g; $value =~ s/\n//g; } # 削除情報 if ($name eq 'del') { push(@DEL,$value); } $in{$name} = $value; } if ($in{'url'} eq "http://") { $in{'url'} = ''; } $mode = $in{'mode'}; } #----------------# # エラー処理 # #----------------# sub error { if ($lockkey) { &unlock; } &header if (!$head_flag); print <<"EOM";

    ERROR !

    $_[0]


    EOM exit; } #--------------# # HTMLヘッダ # #--------------# sub header { $head_flag = 1; print "Content-type: text/html\n\n"; print <<"EOM"; $title EOM } #----------------# # 時間を取得 # #----------------# sub get_time { $ENV{'TZ'} = "JST-9"; ($sec,$min,$hour,$mday,$mon,$year,$wday,$dmy,$dmy) = localtime(time); # 日時のフォーマット @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); if (!$_[0]) { $Date = sprintf("%04d/%02d/%02d (%s)", $year+1900,$mon+1,$mday,$week[$wday]); } else { $Date = sprintf("%04d/%02d/%02d(%s) %02d:%02d", $year+1900,$mon+1,$mday,$week[$wday],$hour,$min); } } #----------------# # ホスト名取得 # #----------------# sub get_host { $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($gethostbyaddr) { if ($host eq "" || $host eq "$addr") { $host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2); } } if ($host eq "") { $host = $addr; } } #--------------# # ロック処理 # #--------------# sub lock { if (-e $lockfile) { # 3分以上古いロックは削除する ($mtime) = (stat($lockfile))[9]; if ($mtime < time - 180) { &unlock; } } local($retry) = 5; while (!mkdir($lockfile, 0755)) { if (--$retry <= 0) { &error('Lock is busy'); } sleep(1); } } #--------------# # ロック解除 # #--------------# sub unlock { rmdir($lockfile); } #--------------# # 自動リンク # #--------------# sub auto_link { $_[0] =~ s/([^=^\"]|^)(http\:[\w\.\~\-\/\?\&\=\@\;\#\:\%]+)/$1$2<\/a>/g; }