#!/usr/bin/perl ;# ↑このパスはプロバイダによって違うので調べて設定する ;# (これはこのスクリプトの最初の1行になければならず、それより上に空行があってもいけません。) ;# (この設定が必要ないサーバもあります。一般的な場合を想定して解説を入れています。) ;# (他に、プロバイダからアナウンスされている情報を十分理解しておいてください。) ;# ;# 簡易BBS version 9.03(フリーソフト) ;# ;# Script written by Kazu.Y ;# Created on: 02/05/96 ;# I can be reached at: rescue@ask.ne.jp ;# Scripts Found at: http://www.rescue.ne.jp/ # [History] # v8.90 11/AUG/98 v8.8にロック機能を付加 # v9.00 12/AUG/98 タグ処理を制限してセキュリティアップ # v9.01 24/AUG/98 未入力処理(クッキー消去)時にリストされな不具合を修正 # v9.02 03/SEP/98 改行の扱いを3種類に変更 # v9.03 18/SEP/98 Eメール自動リンクの廃止 ########################################################################################### # # ■重要! v9シリーズはそれ以前のヴァージョンとデータの互換性がありません。 # # 基本構成 # # /public_html/(ホームページディレクトリ) # | # |-- /cgi-bin/(任意のディレクトリ) # | # |-- jcode.pl (755) # |-- minibbs.cgi (755) # | # |-- /data/ (777) # | # |-- minibbs.dat (666) # # ・minibbs.dat は中身が空っぽのファイルをパソコン上で作成して転送する # ・( )内はパーミッッション値 # ########################################################################################### #----------------# # 初期設定 # #----------------# #--- 必ずあなたの環境に合わせて書き替える項目 --------------------------------------------# #◆掲示板の名前 # ''内に記述しますが、'を入れたい場合は '' を "" に替えてください. # ただしその場合、文字によって化けが生じることがあります. # 詳しくは当サイトのFAQを参照してください. $title = '久美沙織オンラインファンクラブ'; #◆このスクリプトをURLで設定 $reload = 'http://www.sasabe.com/SF/kumi/minibbs.cgi'; #◆画面の「終了」リンク先をURLで設定 $modoru = 'http://www.sasabe.com/SF/kumi/'; #--- 必要に応じて設定する項目 ------------------------------------------------------------# #◆画面の色や背景の設定 (HTML書式) $body = ''; #◆タイトル背景とタイトル文字色の設定 $title_back = '#8080ff'; $title_str = '#ffffff'; #◆投稿毎に管理者へ内容をメールする # メール機能は、いち早く不適切な投稿等をチェックすることができるように設計しました. # メールしない場合は $mailto $sendmail を設定する必要はありません. # 投稿者がEメールを記入している場合は、返信アドレスにそのEメールが記載されます. # メールする:1 しない:0 $s_mail = 1; $mailto = 'WJ6Y-SSB@j.asahi-net.or.jp'; # 送信先Eメール $sendmail = '/usr/sbin/sendmail'; # 送信スクリプト(sendmail) プロバイダに聞くこと #◆画面内に記述する文字列等 (HTML書式) # ''内に記述しますが、'を入れたい場合は '' を "" に替えてください. # ただしその場合、文字によって化けが生じることがあります. # 詳しくは当サイトのFAQを参照してください. # 必要ない場合は '' 内に何も書きません. #◇タイトルの下位置に表示する文字列 $msg_top1 = 'ここは、久美沙織さんのファンのための掲示板です。ファンの方は、ご自由に書き込んで下さい。'; $msg_top2 = ''; $msg_top3 = ''; #◇投稿フォームの下位置に表示する文字列 $msg_mid1 = '■投稿時には、この記事を削除する時に利用する削除キーを設定してください.
'; $msg_mid2 = '■一度設定して投稿すれば一定期間同じ削除キーが保存されます.
'; $msg_mid3 = '■入力欄に記憶された内容を消去するには、[書き直し]→[書き込む]を順番に押します.'; #◇最下部に表示する文字列 $msg_btm1 = '■削除は、[削除]欄をチェックして、投稿時に設定した削除キーをすぐ上の欄に入力してボタンを押します.
'; $msg_btm2 = '■削除キーが合致しない記事は削除されません.
'; $msg_btm3 = '■削除キー欄にマスターキー(管理者のみ)を入力するとすべての記事の削除が可能です.'; #◆$reloadで設定した設置URL以外のフォームからの投稿を禁止する処置 する:1 しない:0 # 悪戯の防止用ですが、利用サーバやブラウザによっては正規投稿もできなくなる場合もあります. $ref_axs = 1; #◆1記事の最大記録サイズ(bytes) 0で無制限 $max_size = 0; #◆1画面に表示する記事件数 $def = 10; #◆書き込み件数の最大登録数の設定です。この件数を超えると、古いものから削除されていきます. # ページ処理機能が付きましたので、この件数を大きくしても一度に表示される記事数は限定されます. # 記録されたファイルの巨大化を防止する為に、ある程度の件数で自動削除されるようにします. # サーバ負荷を考慮して、あまり大きくしないことが重要です. $max = '200'; #◆日本語コード変換ライブラリ # minibbs.cgiと同じ場所に設置する場合はこのままでよい. require './jcode.pl'; #◆内容が書き込まれる記録ファイルの名前(パスの設定ではない!) $file = 'minibbs.dat'; #◆データディレクトリのパスの設定(処理の都合上 / で閉じない) $tmp_dir = './data'; #◆海外サーバ等で時差が生じる場合は修正します # 海外時間に+9時間する場合 = localtime(time + 9*60*60); # 海外時間に−9時間する場合 = localtime(time - 9*60*60); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); #◆クッキーの消化設定 # 最終書き込みから 30日後 30*24*60*60 #           1日後 24*60*60 #          10時間後 10*60*60 ($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg,$ydayg,$isdstg) = gmtime(time + 30*24*60*60); #◆入力形式の設定 標準入力:1(post) その他:0(get) # 投稿ボタンを押して Method not implemented.. 等というエラーが出る場合は get で試すこと # getの場合は文字制限がありますので長い文章等は途中で切れる可能性があります. # さらに、getの場合は不要な悪戯を受けてしまう環境になりますので、注意してください. # POST:1 GET:0 $method = 1; ########################################################################################### # # ・記録ファイルには処理の都合上特殊コードが記録されますので、直接編集はできません。 # ・スクリプトの中身を書き替える場合は、perlやCGIやHTMLなどのそれなりの知識が必要です。 # ########################################################################################### @wday_array = ('日','月','火','水','木','金','土'); $date_now = sprintf("%01d月%01d日(%s)%02d時%02d分",$mon +1,$mday,$wday_array[$wday],$hour,$min); $date_num = sprintf("%02d%02d%02d%02d%02d",$mon +1,$mday,$hour,$min,$sec); # <-変更禁止 &lock0; if ($method eq '1' && $ENV{'QUERY_STRING'} ne '') { &error('エラー','不正利用の可能性があります.'); } if ($method eq '1') { $method = 'post'; read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); } else { $method = 'get'; $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/,$buffer); @pairs = (grep(/^action=/,@pairs),grep(!/^action=/,@pairs)); 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 ($value =~ /(.*)\"\,\"(.*)/) { &error('記入ミス','記録できない文字の並び「","」があります.'); } $value =~ s//>/g; if ($s_mail && $name eq 'value') { $mail_value = $value; if ($mail_value =~ /\r\n/) { $mail_value =~ s/\r\n/\n/g; } if ($mail_value =~ /\r/) { $mail_value =~ s/\r/\n/g; } } if ($FORM{'action'} eq 'regist') { if ($value =~ /\r\n/) { $value =~ s/\r\n/\r/g; } if ($value =~ /\n/) { $value =~ s/\n/\r/g; } } if ($name eq 'name' || $name eq 'email') { $value =~ s/\;//g; $value =~ s/\://g; $value =~ s/\,//g; } if ($name eq 'target') { push(@RM,$value); } else { $FORM{$name} = $value; } } if ($FORM{'action'} eq 'password') { &encode; } $cookies = $ENV{'HTTP_COOKIE'}; @pairs = split(/;/,$cookies); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $name =~ s/ //g; $DUMMY{$name} = $value; } @pairs = split(/,/,$DUMMY{$reload}); foreach $pair (@pairs) { ($name, $value) = split(/:/, $pair); $COOKIE{$name} = $value; } if ($FORM{'admin'} eq 'change') { &password; exit; } if ($FORM{'action'} eq 'remove') { &remove; } elsif ($FORM{'action'} eq 'regist') { ®ist; } if (!open(DB,"$tmp_dir\/$file")) { &error('設定ミス',"$file が設定された場所にありません."); } @lines = ; close(DB); if (-z "$tmp_dir\/$file") { $first = 1; &password; exit; } elsif (@lines[0] =~ /MiniBBSv8/) { &error('データエラー',"$file のデータ形式は簡易BBSv8シリーズのものと思われますので使えません."); } elsif (!(@lines[0] =~ /MiniBBSv9/)) { &error('データエラー',"$file のデータはこの簡易BBSでは使えない構造である可能性があります."); } &html; exit; sub html { #--- 入力フォーム画面 --------------------------------# print "Content-type: text/html\n\n"; print "$title\n"; print "$body\n"; print "
\"トップページ\" \"ハードSF研究所ご案内\" \"東野司オンラインファンクラブ\" \"橋元淳一郎オンラインファンクラブ\" \"久美沙織オンラインファンクラブ\" \"平谷美樹オンラインファンクラブ\" \"感想文データベース\" \"sf-retro-mlご紹介\" \"WebMagazine
\n"; print "
\n"; print "
\n"; print "

\n"; print "

$title

\n"; print "$msg_top1\n"; print "$msg_top2\n"; print "$msg_top3

\n"; print "

\n"; print "\n"; print "\n"; print "\n"; print "
新掲示板はこちらから

\n\n"; print "\n"; print "\n"; print "
旧掲示板はこちらから

\n\n"; print "\n"; print "\n"; print "
久美沙織感想ノート

\n\n"; #--- 記録記事の出力 ----------------------------------# @lines = reverse(@lines); if ($FORM{'page'} eq '') { $page = 0; } else { $page = $FORM{'page'}; } $page_end = $page + $def - 1; if ($page_end > $#lines) { $page_end = $#lines; } print "\n"; print "\n"; foreach ($page .. $page_end) { if ($lines[$_] =~ /^\"(\d+)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\",\"(.*)\"/) { $number = $1; $pwd = $2; $name = $3; $email = $4; $host = $5; $date = $6; $subject = $7; $link = $9; $how = $10; $value = $8; $value =~ s//>/g; if ($link == 1) { $value =~ s/>/\t/g; $value =~ s/(https?|ftp|gopher|telnet|whois|news)\:([\w|\:\!\#\$\%\=\&\-\^\`\\\|\@\~\[\{\]\}\;\+\*\,\.\?\/]+)/$1\:$2<\/a>/ig; $value =~ s/\t/>/g; } print "


\n"; print "
$subject
\n"; print "投稿日 $date "; if ($email) { print "投稿者
$name [$host] "; } else { print "投稿者 $name [$host] "; } print "削除

\n"; print "

\n"; if ($how == 1) { print "
$value

\n"; } elsif ($how == 2) { $value =~ s/\r/
\r/g; print "$value

\n"; } else { print "$value

\n"; } print "

\n"; } } #--- 改ページ処理 ------------------------------------# $page_next = $page_end + 1; $i = $page + 1; $j = $page_end + 1; print "

\n"; print "\n"; if ($#lines >= 0) { if ($page_end ne $#lines) { print "\n"; print "\n"; print "\n"; print "\n"; } else { print "\n"; } } print "\n"; print "\n"; print "\n"; print "
削除キー "; print "新着順 $i \- $j
新着順 $i \-> 最後最大記録件数 $max更新終了

\n\n"; print "$msg_btm1\n"; print "$msg_btm2\n"; print "$msg_btm3

\n"; print "\n"; print "\n"; print ""; print "\n"; print "

\n\n"; # このスクリプトの著作権表示(かならず表示してください) print "

MiniBBS v9.03
\n"; print "\n"; } sub regist { if ($ref_axs) { $ref = $ENV{'HTTP_REFERER'}; $ref_url = $reload; $ref_url =~ s/\~/.*/g; if (!($ref =~ /$ref_url/i)) { &error('利用不可',"「$reload」以外からの投稿は受け付けられません."); } } if ($FORM{'name'} eq '') { &error('入力ミス','投稿者を記入してください.'); } $FORM{'name'} =~ s//>/g; if ($FORM{'email'} ne '' && !($FORM{'email'} =~ /(.*)\@(.*)\.(.*)/)) { &error('入力ミス','メールアドレスの形式が間違っています.'); } $FORM{'email'} =~ s//>/g; if ($FORM{'pwd'} eq '' || $FORM{'pwd'} =~ /\W/ || length($FORM{'pwd'}) > 10) { &error('入力ミス','ボタンの右側にある削除キー欄に10文字以内の半角英数字で記入してください.
これは記事の削除時に利用するものです.'); } if ($FORM{'subject'} eq '' && $FORM{'value'} eq '') { $COOKIE{'name'} = ''; $COOKIE{'email'} = ''; $COOKIE{'pwd'} = ''; &cookie; print "Set-Cookie: $reload=\n"; if (!open(DB,"$tmp_dir\/$file")) { &error('設定ミス',"$file が設定された場所にありません."); } @lines = ; close(DB); &html; exit; } if ($FORM{'subject'} eq '') { &error('入力ミス','題名を記入してください.'); } $FORM{'subject'} =~ s//>/g; if ($FORM{'value'} eq '') { &error('入力ミス','内容を記入してください.'); } if ($max_size) { $value_size = length($FORM{'value'}); if ($value_size > $max_size) { &error('入力ミス',"最大記録サイズ$max_sizeを超えています. 現在$value_sizeサイズです."); } } &cookie; $cook="name\:$FORM{'name'}\,email\:$FORM{'email'}\,pwd\:$FORM{'pwd'}"; print "Set-Cookie: $reload=$cook; expires=$date_gmt\n"; #-- リムネット専用ホスト取得ルーチンの入れ替え位置 : ここから --# $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($host eq $addr) { $host = gethostbyaddr(pack('C4',split(/\./,$host)),2) || $addr; } #-- リムネット専用ホスト取得ルーチンの入れ替え位置 : ここまで --# &lock1; if (!open(DB,"$tmp_dir\/$file")) { &error('設定ミス',"$file が見つかりません. 設定を確認してください."); } @lines = ; $password = shift(@lines); close(DB); &encode2($FORM{'pwd'}); if ($max <= $#lines + 1) { shift(@lines); } push(@lines,"\"$date_num\"\,\"$pwd\"\,\"$FORM{'name'}\"\,\"$FORM{'email'}\"\,\"$host\"\,\"$date_now\"\,\"$FORM{'subject'}\"\,\"$FORM{'value'}\"\,\"$FORM{'link'}\"\,\"$FORM{'how'}\"\n"); if (!open(DB,"> $tmp_dir\/$tmp_file")) { &error('設定ミス','テンポラリーファイルが作成できません.'); } print DB $password; print DB @lines; close(DB); &lock2; $COOKIE{'name'} = $FORM{'name'}; $COOKIE{'email'} = $FORM{'email'}; $COOKIE{'pwd'} = $FORM{'pwd'}; if ($s_mail) { &e_mail; } } sub cookie { 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"; } $y0="Sunday"; $y1="Monday"; $y2="Tuesday"; $y3="Wednesday"; $y4="Thursday"; $y5="Friday"; $y6="Saturday"; $youbi = ($y0,$y1,$y2,$y3,$y4,$y5,$y6) [$wdayg]; $m0="Jan"; $m1="Feb"; $m2="Mar"; $m3="Apr"; $m4="May"; $m5="Jun"; $m6="Jul"; $m7="Aug"; $m8="Sep"; $m9="Oct"; $m10="Nov"; $m11="Dec"; $month = ($m0,$m1,$m2,$m3,$m4,$m5,$m6,$m7,$m8,$m9,$m10,$m11) [$mong]; $date_gmt = "$youbi, $mdayg\-$month\-$yearg $hourg:$ming:$secg GMT"; } sub error { print "Content-type: text/html\n\n"; print "$title\n"; print "$body\n"; print "

$_[0]

\n"; print "

$_[1]

\n"; print "ブラウザの[戻る]ボタンを押して前の画面に移動してください.

\n"; print "\n"; exit; } sub remove { &lock1; if (!open(DB,"$tmp_dir\/$file")) { &error('設定ミス',"$file が見つかりません. 設定を確認してください."); } @lines = ; close(DB); $password = shift(@lines); chop($password); ($header,$password1) = split(/:/,$password); if ($password1 =~ /^\$1\$/) { $salt = 3; } else { $salt = 0; } $target = join('|',@RM); if (crypt($FORM{'pwd'}, substr($password1,$salt,2)) eq $password1) { $admin = 1; } foreach $line (@lines) { if ($line =~ /^\"(\d+)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\"\,\"(.*)\",\"(.*)\"/) { $number = $1; $pwd = $2; if ($number =~ /$target/) { if (!$admin && crypt($FORM{'pwd'}, substr($pwd,$salt,2)) ne $pwd) { push(@NEW,$line);} } else { push(@NEW,$line); } } } if (!open(DB,"> $tmp_dir\/$tmp_file")) { &error('設定ミス','テンポラリーファイルが作成できません.'); } print DB "$password\n"; print DB @NEW; close(DB); &lock2; @lines = @NEW; } sub password { if (-z "$tmp_dir\/$file") { $first = 1; } print "Content-type: text/html\n\n"; print "$title\n"; print "$body\n"; print "

マスターキーの設定/変更

\n"; if ($first && $message eq '') { print "記事を削除するための管理パスワードを登録します。

\n"; } else { print "$message

\n"; } print "

\n"; print "\n"; if (!$first) { print "旧パスワード
\n"; } print "新パスワード
\n"; print "新パスワード (確認のためもう一度)

\n"; print "

\n"; print "\n"; } sub encode { &lock1; if (!open(DB,"$tmp_dir\/$file")) { &error('設定ミス',"$file が見つかりません. 設定を確認してください."); } @lines = ; close(DB); $password = shift(@lines); chop($password); ($header,$password1) = split(/:/,$password); if ($password1 =~ /^\$1\$/) { $salt = 3; } else { $salt = 0; } if ($header eq 'MiniBBSv9') { if (crypt($FORM{'password_old'}, substr($password1,$salt,2)) ne $password1) { $message = '旧パスワードが認証されませんでした.'; &password; exit; }} if ($FORM{'pwd'} =~ /\W/ || $FORM{'pwd'} eq '') { $message = '新パスワードに英数字以外の文字が含まれているか空欄です.'; &password; exit; } if ($FORM{'pwd'} ne $FORM{'pwd2'}) { $message = '確認のために入力された新パスワードが一致しません.'; &password; exit; } &encode2($FORM{'pwd'}); if (!open(DB,"> $tmp_dir\/$tmp_file")) { &error('設定ミス','テンポラリーファイルが作成できません.'); } print DB "MiniBBSv9\:$pwd\n"; print DB @lines; close(DB); &lock2; &html; exit; } sub encode2 { $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]; if (!eval '$pwd = crypt($_[0], $nsalt);') { &error('エラー','暗号処理コマンドが使えませんので設置できません.'); } } sub e_mail { # 管理者に投稿をメールする if (!open(OUT,"| $sendmail -t")) { return; } print OUT "To: $mailto\n"; if ($FORM{'email'} ne '') { print OUT "From: kumibbs\@sasabe.com\n"; } else { print OUT "From: kumibbs\@sasabe.com\n"; } $subject = "[$title] 新着情報"; &jis("Subject: $subject"); print OUT "$msg\n"; print OUT "Content-Transfer-Encoding: 7bit\n"; print OUT 'Content-Type: text/plain; charset=iso-2022-jp' . "\n\n\n"; &jis("投稿者: $FORM{'name'}"); print OUT "$msg\n"; &jis("Eメール: $FORM{'email'}"); print OUT "$msg\n"; &jis("題名: $FORM{'subject'}"); print OUT "$msg\n"; &jis("\n$mail_value"); print OUT "$msg\n\n"; close(OUT); } sub jis { $msg = $_[0]; &jcode'convert(*msg, 'jis'); } sub lock0 { $ps = $$; if ($ps eq '') { $ps = $date_num; } $tmp_file = "$ps\.tmp"; $ls = "$tmp_dir\/*\.tmp"; } sub lock1 { $list = `ls $ls`; @lists = split(/\s+/,$list); local($retry) = 3; while (@lists) { if (--$retry <= 0) { foreach (@lists) { unlink; } &error("Busy(1)",'ただ今混雑しております.
再度実行してください.'); } sleep(1); $list = `ls $ls`; @lists = split(/\s+/,$list); } } sub lock2 { $list = `ls $ls`; @lists = split(/\s+/,$list); @lists = grep(!/$tmp_file/,@lists); if (@lists) { unlink("$tmp_dir\/$tmp_file"); &error("Busy(2)",'書き込みに失敗しました.
再度実行してください.'); } if (!rename("$tmp_dir\/$tmp_file","$tmp_dir\/$file")) { &error("Busy(3)",'書き込みに失敗しました.
再度実行してください.'); } ; chmod 0666,"$tmp_dir\/$file"; }