#!/usr/bin/perl # ---------------------------------------------------------- # バナナの管理者(あなた)の情報です。 # ---------------------------------------------------------- require '../forbidden/forbidden.pl'; $admin_name = '邑波。'; # あなたの名前(ハンドルネーム)を書きます。 $admin_email = 'yuuha@waterblue.net'; # あなたのメールアドレスを書きます。 $master = 'a600c970'; # 管理用のパスワード # ---------------------------------------------------------- # バナナのカスタマイズ項目です。 # ---------------------------------------------------------- $cgi_title = 'FF連想げーむ'; # バナナのタイトル(タグ不可) $body_text = '#ffffff'; # タグの設定 $body_link = ''; # リンクの色 $body_alink = ''; # クリック中のリンクの色 $body_vlink = ''; # 既にクリック済みのリンクの色 $body_bgcolor = '#000000'; # 背景の色 $body_back = ''; # 背景画像 $back_url = "http://union.waterblue.net/"; # 帰りの URL(絶対URL推奨) $image_banana = 'banana.gif'; # バナナの画像のある URL $date_color = "#666666"; # 日付の色 $emb_color = "#666666"; # 強調色 $oldcolor = "#3333CC"; # バナナ(連想単語)の色(^-^;; (はじめ) $newcolor = "#3333CC"; # バナナ(連想単語)の色(^-^;; (あと) $limit_log = 200; # ログの最大登録数 $page = 50; # 1ページに表示するバナナの数(^-^;; $ip_check = 1; # IPアドレスの表示 (0:表示しない 1:表示する) $rh_check = 1; # リモートホストの表示 (0:表示しない 1:表示する) # ファイル関連の設定 $method = 'POST'; # METHOD の設定('POST' or 'GET') $tz = 'JST-9'; # TimeZone $cginame = 'index.cgi'; # この CGI のファイルの名前 $jcode = './jcode.pl'; # jcode.pl のある場所 $savetype = 0; # ログの記録方式 0:標準(推奨) 1:Temp利用 $logdir = './'; # 記録用ファイルの置くディレクトリへのパス(URLじゃないよ) $logfile = 'banana.log'; # 記録用ファイル名 $lock1 = 'banana1.lock'; # 鍵ファイル名(1) $lock2 = 'banana2.lock'; # 鍵ファイル名(2) $lock_flag = 1; # 鍵ファイルの 1:使用 0:不使用 # HTML関連の設定 # -------------------- # タイトル部分の HTML文 $html_title=<<"_EOF_";

FF連想ゲ〜ム

_EOF_ # -------------------- # 説明部分の HTML文(上) $html_info_top =<<"_EOF_";
前にここに来た人が残した下の言葉から、あなたが連想した言葉を書いて下さい。
ちゃんと書かないと見せてあげません。
連想は基本的にファイナルファンタジーに関するものに限定します.
そうでなくてもぜいぜい一般概念(熱い,赤いなど)にしてください.
_EOF_ # ↑ この _EOF_ はこのままにしておくこと! # -------------------- # 説明部分の HTML文(下) $html_info_bottom =<<"_EOF_";
・ タグを使用したり、全角 30字を超えると登録されません。
・ 続けて投稿したり、発想力に乏しいと登録されないらしいです。
_EOF_ # -------------------- # 登録後のサンキューメッセージ $html_thanks =<<"_EOF_";
これまでの連想を見て楽しんでください。
今度はあなたの言葉からどんな連想がされていくのか楽しみです。

_EOF_ # -------------------- # 独自の JavaScript や スタイルシートはここに $html_head=<<"_EOF_"; _EOF_ # -------------------- # 上にバナー(広告)をつける必要があるならここに $html_topbanner=<<"_EOF_"; _EOF_ # -------------------- # 下にバナー(広告)をつける必要があるならここに $html_bottombanner=<<"_EOF_"; _EOF_ # ////////////////////////////////////////////////////////// # オプションの設定はここまでです。 # 以下は CGI のプログラムです。 # 書き換えは個人の責任で行って下さい。 # ////////////////////////////////////////////////////////// $logdir =~ s/\/$//; $logfile = "$logdir/$logfile"; $lock1 = "$logdir/$lock1"; $lock2 = "$logdir/$lock2"; if ($limit_log < 30) { $limit_log = 30; } if ($limit_log > 9900) { $limit_log = 9900; } &check_code; &access_check; &read_form; if ($FORM{'mode'} eq 'test') { &check_mode; } elsif ($FORM{'mode'} eq 'admin') { &html_admin_enter; } elsif ($FORM{'pass'} eq $master) { # 入力欄 @logs = &read_file($logfile); $FORM{'banana'} = &encode_text($FORM{'banana'}); &edit_editor; print "Content-type: text/html\n\n"; &html_editor; } elsif ($FORM{'mode'} eq 'view') { # ログ表示 @logs = &read_file($logfile); print "Content-type: text/html\n\n"; &html_header; print $html_title; print "
\n"; print $html_thanks; print "
\n"; print "
\n"; &html_banana(&page_banana); &html_footer; } elsif ($FORM{'banana'}) { # 登録処理 @logs = &read_file($logfile); $FORM{'banana'} = &encode_text($FORM{'banana'}); &check_banana; ®ist_banana; print "Content-type: text/html\n\n"; &html_header; print $html_title; print "
\n"; print $html_thanks; print "
\n"; print "
\n"; &html_banana(&page_banana); &html_footer; } else { # DefaultHTML出力 @logs = &read_file($logfile); print "Content-type: text/html\n\n"; &html_header; print $html_title; print $html_info_top; &html_default; print $html_info_bottom; &html_footer; } exit 1; # [ HTMLヘッダー部 ] # sub html_header{ print<<"_EOF_"; $cgi_title $html_head $html_topbanner
[$admin_name専用] [バナナから戻る]
_EOF_ } # [ 著作権の表示(書き換えずに、必ず表示すること) ] # sub html_footer{ print<<"_EOF_";
WeB BaNaNa Version 2.21
[ 管理者:$admin_name 配布元:ShigetoNakazawa ]
$html_bottombanner _EOF_ } # [ DefaultHTML 出力 ] # sub html_default { # 最近登録されたものを取得する if (!$logs[0]) { $logs[0] = "0<>xx/xx xx:xx<>バナナ<><><>$time\n"; &write_file($logfile,$logs[0]); } ($no,$date,$banana) = split(/<>/,$logs[0]); $banana = &decode_text($banana); # HTML出力 print<<"_EOF_";

$banana といったら



_EOF_ } # [ 管理人入り口 ] # sub html_admin_enter { print "Content-type: text/html\n\n"; print<<"_EOF_"; WeB BaNaNa Editor


管理用パスワードを入力してください。

(管理用のエディタを使用するためには、管理用パスワードが必要です。)

_EOF_ } # [ バナナページ(^-^;; ] # sub page_banana{ $start = $FORM{'page'}; $end = $start + $page + 1; if ($end >= @logs) { $end = @logs; } else { $next =$end - 1; print "
\n"; print "[過去のワード]\n"; print "
\n"; } if ($start <= 0) { $start = 0; } return ($start,$end); } # [ バナナ出力 ] # sub html_banana { ($start,$end) = @_; print "
\n"; for($i=$start;$i<$end;$i++) { ($no,$date,$banana,$rhost,$ipad) = split(/<>/,$logs[$i]); $word = &decode_text($banana); if ($tword) { print ""; print "[$tdate] "; print "$word"; print " といったら "; print "$tword"; if ($ip_check || $rh_check) { print " ("; if ($ip_check) { print $ipad ." / "; } if ($rh_check) { print $rhost; } print ")"; } print "\n
\n"; } $tword = $word; $tdate = $date; } } # [ バナナ登録チェック ] # sub check_banana { # 最近登録されたデータを取得 ($no,$date,$banana,$rhost,$ipad,$time) = split(/<>/,$logs[0]); $nowtime = time; # 登録順番をチェック if ($FORM{'no'} != $no) { &error(1,"残念、誰かが先に連想してしまったみたいです。
一度、戻って再読み込みしてから連想してください。"); } # 同じサイトからの連続投稿は拒否 if ($ipad eq $ENV{'REMOTE_ADDR'} && $nowtime - $time < 120) { &error(1,"連続しての投稿はできません。"); } # 文字制限チェック if (length($FORM{'banana'}) > 60) { &error(1,"連想ワードは文字数は全角30字を超えてはいけません。"); } # タグ制限チェック if ($FORM{'banana'} =~ //) { &error("タグを使ってはいけません。"); } # 連想ワードを過去の情報と照合する foreach (@logs) { $banana = (split(/<>/,$_))[2]; if (($banana =~ /$FORM{'banana'}/i) || ($FORM{'banana'} =~ /$banana/i)) { &error(1,"前にあなたと同じような発想をした人がいるようです。
戻って発想し直してください。"); } } } # [ バナナ登録処理 ] # sub regist_banana { # 連番のために $FORM{'no'} = ++$FORM{'no'} % 9999; # 日付取得 ($year,$mon,$day,$hour,$min,$sec,$youbi) = &get_date($tz); $time = time; # ホスト情報取得 local($ipad,$rhost) = ($ENV{'REMOTE_ADDR'},$ENV{'REMOTE_HOST'}); $rhost = $rhost eq $ipad?gethostbyaddr(pack('C4',split(/\./,$ipad)),2)||'':$rhost; # ログ更新 unshift(@logs,"$FORM{'no'}<>$mon/$day $hour:$min<>$FORM{'banana'}<>$rhost<>$ipad<>$time\n"); # ログ制限 while(@logs > $limit_log) { pop(@logs); } &write_file($logfile,@logs); } # [ エディター表示 ] # sub html_editor { print<<"_EOF_"; WeB BaNaNa Editor
[エディタをやめる]

WeB BaNaNa Editor

★使い方★

編集する時
1.編集する項目をチェックします。(複数でも可能\)
2.編集内容を書きます(このとき、何も書かなかった場合、削除されます)
3.[編集開始]で書き換えられます。



_EOF_ foreach (@logs) { ($no,$date,$banana,$rhost,$ipad) = split(/<>/,$_); $banana = &decode_text($banana); print "\n"; print "$date : "; print "$banana($rhost/$ipad)\n"; print "
\n"; } print "\n"; } # [ エディット ] sub edit_editor { $flag = 0; $no = ((split(/<>/,$logs[0]))[0] + 1) % 9999; foreach (@logs) { local($no,$date,$banana,$rhost,$ipad,$time) = split(/<>/,$_); if ($del{$no}) { $flag = 1; if ($FORM{'banana'}) { push (@new,"$no<>$date<>$FORM{'banana'}<>$rhost<>$ipad<>$time"); } } else { push (@new,$_); } } if ($flag) { undef (@logs); @logs = &write_file($logfile,@new); } undef (@new); } # [ CGI動作チェック ] # sub check_mode { if (!(-f $logfile)) { $axs = "Not Found" } if (-r $logfile) { $axs = "r" } if (-w $logfile) { $axs .= "w" } print "Content-type: text/html\n\n"; print<<"_EOF_";
    WeB BaNana Version 2.21 -TestMode-

[Option] logfile[$axs] LockFlag:$lock_flag SaveType:$savetype Method:$method FileName:$cginame TimeZone:$tz Owner:$admin_name ($admin_email)

[Perl] Path:#!$^X Version:$]

[TestForm] TestFormText:$FORM{'test'}

_EOF_ exit; } # [ 禁止文字コードの変換処理 ] # sub encode_text { # エンコード local($text) = $_[0]; $text =~ s/\(/(/g; $text =~ s/\)/)/g; $text =~ s/\*/*/g; $text =~ s/\+/+/g; $text =~ s/\././g; $text =~ s/\?/?/g; $text =~ s/\[/[/g; $text =~ s/\\/\/g; $text =~ s/\]/]/g; $text =~ s/\{/{/g; $text =~ s/\|/|/g;$text =~ s/\}/}/g; return $text; } sub decode_text { # デコード local($text) = $_[0]; $text =~ s/(/\(/g; $text =~ s/)/\)/g; $text =~ s/*/\*/g; $text =~ s/+/\+/g; $text =~ s/./\./g; $text =~ s/?/\?/g; $text =~ s/[/\[/g; $text =~ s/\/\\/g; $text =~ s/]/\]/g; $text =~ s/{/\{/g; $text =~ s/|/\|/g;$text =~ s/}/\}/g; return $text; } # [ 記録ファイルの処理 ] # sub read_file { local($logfile) = $_[0]; if (!open(IN,$logfile)) { &error(1,"記録ファイルの読み込み不可"); } local(@files) = ; close(IN); return @files; } sub write_file { local($logfile,@lines) = @_; &dubble_lock_file; if ($lock_error) { &error(1,"ロックファイルを検出しました。時間をおいてご利用下さい。"); } if (!$savetype) { # 標準タイプ 全 OS 共通 if (!open(OUT,">$logfile")) { &dubble_unlock_file; &error(1,"記録ファイルの書き込み不可"); } print OUT @lines; close(OUT); } else { # 改良タイプ chmod 使用(プロバイダによっては使えない) $tmpfile = "$$\.tmp"; if (!open(OUT,">$tmpfile")) { &dubble_unlock_file; &error(1,"Temp利用ログ記録方式に未対応です。"); } close(OUT); chmod 0666,$tmpfile; if (!open(OUT,">$tmpfile")) { &dubble_unlock_file; &error(1,"Temp利用ログ記録方式に未対応です。"); } print OUT @lines; close(OUT); rename($tmpfile,$logfile); if (-e $tmpfile) { unlink($tmpfile); } } &dubble_unlock_file; return @lines; } # [ ロック機構 ] # sub dubble_lock_file { if (!(&lock_file($lock1))) { &dubble_unlock_file; } elsif (!(&lock_file($lock2))) { &dubble_unlock_file; } } sub dubble_unlock_file { &unlock_file($lock2);&unlock_file($lock1); } sub lock_file { local($lockfile) = $_[0]; if (!$lock_flag) { return 1; } local($retry) = 3; # ゴミのロックファイルは除去する while (-f $lockfile) { if ($retry-- <= 0) { local($mtime) = (stat($lockfile))[9]; if ($mtime < time()-60*15) { return 0; } $lock_error = 1; return 1; } sleep 1; } open (LOCK,">$lockfile"); close(LOCK); return 1; } sub unlock_file { local($lockfile) = $_[0]; unlink($lockfile); } # [ 日付を取得する ] # sub get_date { $ENV{'TZ'} = $_[0]; local($sec,$min,$hour,$day,$mon,$year,$youbi) = localtime(time); $mon++; if ($sec < 10) { $sec = "0$sec"; } if ($min < 10) { $min = "0$min"; } if ($hour < 10) { $hour = "0$hour"; } if ($day < 10) { $day = "0$day"; } if ($mon < 10) { $mon = "0$mon"; } if ($year < 99) { $year += 100; } $year += 1900; $youbi = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat')[$youbi]; return ($year,$mon,$day,$hour,$min,$sec,$youbi); } # [ フォームからデータ取得 ] # sub read_form { # 標準入力からデータもらう if ($ENV{'REQUEST_METHOD'} eq "POST") { if ($ENV{'CONTENT_LENGTH'} > 1024 * 99) { &error(1,"書き込みすぎです。"); } read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } # デコードする foreach (split(/&/,$buffer)) { local($name,$value) = split(/=/,$_); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $value =~ s/<>/<>/g; $value =~ s/\"/"/g; $value =~ s/\r\n//; $value =~ s/\r|\n//; if ($name eq 'del') { $del{$value} = 1; } else { $FORM{$name} = &change_code($value); } } } # [ 文字コード関連 ] # sub check_code { if (!(-r $jcode)) { &error(1,"jcode.pl がみつかりません。"); } require $jcode; local($text) = ord(substr("中澤重人=じゃわ(^-^;;",0,1)); if ($text == 0xc3) { $mojicode = "euc"; $charset_code = "x-euc-jp"; } elsif ($text == 0x92) { $mojicode = "sjis";$charset_code = "x-sjis"; } else { &error(1,"サポートしてない文字コードです"); } } sub change_code { local($text)=$_[0]; &jcode'convert(*text,$mojicode); if ($mojicode eq 'sjis') { &jcode'h2z_sjis(*text); } if ($mojicode eq 'euc') { &jcode'h2z_euc(*text); } return $text; } # [ エラー処理 ] # sub error { ($err,$err_msg) = @_; if ($err) { print "Content-type: text/html\n\n"; } print<<"_EOF_";
坂〇さんに突っ込まれてしまいました。

$err_msg

[ WeB BaNaNa ]
_EOF_ exit; }