#!/usr/bin/perl ## Monkey Banana v1.0 ## (C) 1997-99 Kent Web (1999/11/03) ## E-Mail webmaster@kent-web.com ## Home http://www.kent-web.com/ $ver = 'Monkey v1.0'; ## ---[注意事項ほか]-------------------------------------------------- ## 1. このスクリプトはフリーソフトです。このスクリプトを使用したいか ## なる損害に対して作者は一切の責任を負いません。 ## 2. 設置に関する質問はサポート掲示板にお願いいたします。メールによる ## 質問はご遠慮ください。 ## 3. 同梱のアイコンは「牛飼いとアイコンの部屋」http://www.ushikai.com/ ## によるものです。 ## ------------------------------------------------------------------- #============# # 設定項目 # #============# # 文字コード変換ライブラリの取り込み require './jcode.pl'; # タイトル名 $title = "Monkey Banana"; # タイトルの文字色 $t_color = "#FFFF00"; # 管理用パスワード $pass = '1123'; # スクリプト名 $script = "monkey.cgi"; # ログファイル $logfile = "./monkey.log"; # 背景色・文字色 $bgcol = "#00B500"; # 背景色 $text = "#FFFFFF"; # 文字色 $link = "#FFDFFF"; # リンク色:未訪問 $vlink = "#FFDFFF"; # リンク色:既訪問 $alink = "#DD0000"; # リンク色:訪問中 # 戻り先(絶対パスならhttp://から記述) $home = "http://www.yuni-net.com/"; # 最大記事数 $max = 100; # カウンタ機能 (0=no 1=テキスト 2=画像) $counter = 1; # カウンタファイル $cntfile = "./count.dat"; # カウンタの桁数 $mini_fig = 5; # カウンタの色(テキストの場合) $cnt_color = "#FFFF00"; # カウンタ画像の大きさ(画像を使用する場合) $mini_w = '16'; $mini_h = '26'; # ロックファイル機能 (0=no 1=yes) $lockkey = 0; # ロックファイル名 $lockfile = "monkey.lock"; # ロックファイルディレクトリ # --> このディレクトリのパーミッションは 777 に設定 $lockdir = "."; # 他サイトからの投稿を禁止する場合 http://からURLを記述 $base_url = ""; # 画像ファイルを置く「ディレクトリ」 # --> 絶対パスだとhttp://からディレクトリを記述(最後に / は不要) $imgurl = "."; # 連続投稿の間隔秒数 $term = 60; # 拒否ホスト @denyhost = ( 'www.proxy.com', '*.hogehoge.ne.jp', 'TKY*.*.odn.*.jp', '', '', '', ''); # 拒否ワード @denyword = ( 'アホ', 'あほ', 'ばか', '馬鹿', 'バカ', 'うんこ', 'ウンコ', '', ''); # ホスト名取得モード # --> 0 : $ENV{'REMOTE_HOST'} で取得できる場合 # --> 1 : gethostbyaddr で取得できる場合 $get_remotehost = 1; # methodプロパティ (POST or GET) $method = 'POST'; #============# # 設定完了 # #============# # ロックファイルを再定義 $lockfile = "$lockdir\/$lockfile"; # 画像ディレクトリで末尾の / を削除 $imgurl =~ s/\/$//; &decode; if ($mode eq 'regist') { ®ist; } if ($mode eq 'home') { &home; } if ($mode eq 'howto') { &howto; } if ($mode eq 'enter') { &enter; } if ($mode eq 'admin') { &admin; } if ($mode eq 'delete') { &delete; } if ($mode eq 'kuji') { &kuji; } &html; ## --- メニュー表示 sub html { # ホストチェック if ($mode ne 'regist') { &host_chk; } # ログを読み込み open(IN,"$logfile") || &error("Can't open $logfile"); $line = ; close(IN); ($num,$date,$word,$agent,$host,$times) = split(/<>/, $line); if ($num eq "") { $num = 1; } if ($word eq "") { $word = "オサル"; } &header; # カウンタ if ($counter) { &counter; } print <<"EOM";

$title

  • 前の方が残した下の言葉から、あなたが連想した言葉を登録して下さい。
  • 登録されると今までの連想された言葉を全て見ることができます。

$word といったら・・





- Monkey Banana -
EOM exit; } ## --- 書きこみ処理 sub regist { # 時間を取得 &get_time; # ホストを取得 &host_chk; # 他サイトからのアクセスを排除 if ($base_url) { $ref_url = $ENV{'HTTP_REFERER'}; $ref_url =~ s/\?(.|\n)*//ig; $ref_url =~ s/\%7E/\~/ig; if ($ref_url ne "" && $ref_url !~ $base_url) { &error("不正なアクセスです。"); } } # 禁止ワードチェック &word_chk; # タグチェック if ($word =~ //) { &error("タグを使用することはできません。"); } # 文字数チェック if ($word eq '') { &error("言葉が入力されていません。"); } if (length($word) > 50) { &error("全角で25文字を超える言葉は登録できません。"); } # ロック開始 if ($lockkey) { &lock; } open(IN,"$logfile") || &error("Open Error : $logfile"); @lines = ; close(IN); if ($lines[0] eq "") { $lines[0] = "1<>$date<>オサル<><><><>\n"; } ($hno,$hdate,$hword,$hagent,$hhost,$htimes) = split(/<>/, $lines[0]); # 同一ホストからの投稿は一定間隔の秒数をおく if ($host eq "$hhost" && $times - $htimes < $term) { &error("連続登録は$term秒以上待ってね。"); } # 1つ前の言葉をチェック if ($no ne "$hno") { &error("残念、誰かが先に連想してしまったようです。もう1度戻って再読み込みして下さい。"); } # 過去の言葉をチェック $flag=0; foreach (@lines) { local($no,$date,$wd,$agent,$host,$ts) = split(/<>/, $_); if ($wd eq "$word") { $flag=1; last; } } if ($flag) { &error("誰かが同じ言葉を連想したことがあるようです。他の言葉を連想し直してみてください。"); } # 記事NOを採番 $no = $hno + 1; # 最大記事数をチェック while ($max <= @lines) { pop(@lines); } unshift(@lines,"$no<>$date<>$word<>$ENV{'HTTP_USER_AGENT'}<>$host<>$times<>\n"); # ログを更新 open(OUT,">$logfile") || &error("Write Error : $logfile"); print OUT @lines; close(OUT); # ロック解除 &unlock; # 完了メッセージ &header; print <<"EOM";

連想してくれてありがとう。

  • 連想してくれてありがとう。以下のとおりに登録されました。
  • これからも貴方の言葉がどのように連想されていくかを見に来て下さいね。

[バナナに戻る] [ホームに戻る]


EOM # 履歴ログを展開 foreach (1 .. $#lines) { $p_word = $word; $p_date = $date; ($no,$date,$word,$agent,$host,$times) = split(/<>/, $lines[$_]); print "$p_date : "; print "$word といったら、"; print "$p_word
\n"; } print "\n"; exit; } ## --- 管理画面入室 sub enter { &header; print <<"EOM";
管理モード

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

EOM exit; } ## --- 管理モード sub admin { # パスチェック if ($FORM{'pass'} ne "$pass") { &error("パスワードが違います。"); } open(IN,"$logfile") || &error("Can't write $logfile"); @lines = ; close(IN); &header; print <<"EOM"; [バナナに戻る] [HOMEに戻る]
管理モード


EOM foreach $line (@lines) { local($no,$date,$wd,$agent,$host,$times) = split(/<>/, $line); print " "; print "$date $wd ($host / $agent)
\n"; } print "\n"; print "\n"; exit; } ## --- 削除処理 sub delete { # パスチェック if ($FORM{'pass'} ne "$pass") { &error("パスワードが違います。"); } # ロック開始 if ($lockkey) { &lock; } open(IN,"$logfile") || &error("Can't write $logfile"); @lines = ; close(IN); @new=(); foreach $line (@lines) { $flag=0; ($no,$date,$wd,$agent,$host,$times) = split(/<>/, $line); foreach (@DEL) { if ($_ eq "$no") { $flag=1; last; } } if ($flag == 0) { push(@new,$line); } } # 更新 open(OUT,">$logfile") || &error("Can't write $logfile"); print OUT @new; close(OUT); # ロック解除 &unlock; # 初期画面に戻る &admin; } ## --- 注意事項 sub howto { &header; print <<"EOM"; [もどる]
$title の遊び方

  • これは単純な「言葉あそび」です。前の人が残した言葉から、連想する言葉を登録して下さい。

  • 登録が完了すると、これまで登録された言葉の一覧を全て見ることができます。

  • 登録される言葉は最大で $max件です。それを超えると古い順に削除されていきます。

  • 1度言葉を登録すると、次の方が登録されるか、又は $term秒間を経過しない限りは「連続した」登録はできません。

  • 全角で25文字を超える言葉は登録できません。

  • 半角カナは文字バケの原因となるため、使用しないで下さい。

  • 「タグ」を使用することはできません。

  • 管理者が不適当な言葉と判断する場合は削除することがあります。

  • この Monkey Banana は元々じゃわ氏が作成した Web BaNaNa からアイデアを頂いて KENT が作成したものです。オリジナルは ここ で入手することができます。

EOM exit; } ## --- 戻り処理 sub home { # IISサーバ(PerlIS)対応 if ($ENV{PERLXS} eq "PerlIS") { print "HTTP/1.0 302 Temporary Redirection\r\n"; print "Content-type: text/html\n"; } print "Location: $home\n\n"; exit; } ## --- ホストチェック sub host_chk { &get_host; local($flag) = 0; foreach (@denyhost) { if ($_ eq '') { next; } $_ =~ s/\*/\.\*/g; # マッチング if ($host =~ /$_/) { $flag=1; last; } } if ($flag) { &error("書き込み中断中だぞ〜♪"); } } ## --- 禁止ワードチェック sub word_chk { local($match) = 0; foreach (@denyword) { if ($_ eq '') { next; } # マッチング if (index($word,$_) >= 0) { $match=1; last; } } if ($match) { &error("使用できない言葉が含まれています。"); } } ## --- フォームからのデータ処理 sub decode { if ($ENV{'REQUEST_METHOD'} eq "POST") { if ($ENV{'CONTENT_LENGTH'} > 51200) { &error("投稿量が大きすぎます。"); } 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; # 文字コード変換 &jcode'convert(*value,'sjis'); # 一括削除用 if ($name eq 'del') { push(@DEL,$value); } $FORM{$name} = $value; } $mode = $FORM{'mode'}; $word = $FORM{'word'}; $word =~ s/ / /g; $word =~ s/\s*$//g; $no = $FORM{'no'}; } ## --- HTMLのヘッダー sub header { print "Content-type: text/html\n\n"; print <<"EOM"; $title EOM } ## --- ホスト名取得 sub get_host { $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($get_remotehost) { if ($host eq "" || $host eq "$addr") { $host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2); } } if ($host eq "") { $host = $addr; } } ## --- エラー処理 sub error { if (-e $lockfile) { unlink($lockfile); } &header; print <<"EOM";

バンドーさんに突っ込まれました!

$_[0]


EOM exit; } ## --- 時間を取得 sub get_time { $ENV{'TZ'} = "JST-9"; $times = time; ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime($times); # 日時のフォーマット @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); $date = sprintf("%02d\/%02d(%s) %02d\:%02d\:%02d", $mon+1,$mday,$week[$wday],$hour,$min,$sec); } ## --- ロックファイル処理 sub lock { local($flag) = 0; foreach (1 .. 5) { if (-e $lockfile) { sleep(1); } else { open(LOCK,">$lockfile") || &error("Can't create LockFile"); close(LOCK); $flag = 1; last; } } if ($flag == 0) { &error("LOCK is BUSY"); } } ## --- ロック解除 sub unlock { if (-e $lockfile) { unlink($lockfile); } } ## --- カウンタ処理 sub counter { # カウントファイルを読みこみ open(NO,"$cntfile") || &error("Can't open $cntfile"); $cnt = ; close(NO); # 閲覧時のみカウントアップ if ($FORM{'mode'} eq '') { # カウントアップ $cnt++; # テンポラリーファイルを定義 $prono = "$$"; if ($prono eq "") { srand; $prono = 1000000000000000 * rand; } $cnt_temp = "$lockdir\/$prono\.ctmp"; # テンポラリーファイルを作成 open(TMP,">$cnt_temp") || &error("Can't create TempFile"); print TMP $cnt; close(TMP); # リネームする chmod (0666,$cnt_temp); rename($cnt_temp,$cntfile); # もしテンポラリーファイルが残っていたら削除 if (-e $cnt_temp) { unlink($cnt_temp); } } # 桁数調整 while(length($cnt) < $mini_fig) { $cnt = '0' . "$cnt"; } @cnts = split(//,$cnt); print "
\n"; # GIFカウンタ表示 if ($counter == 2) { foreach (0 .. $#cnts) { print "\"$cnts[$_]\""; } } # テキストカウンタ表示 else { print "$cnt"; } print "
\n"; } ## --- おみくじ sub kuji { # $kuji[*] と $msg[*] は必ず「同数」にすること。 $kuji[0] = '大吉'; $kuji[1] = '中吉'; $kuji[2] = '吉'; $kuji[3] = '小吉'; $kuji[4] = '末吉'; $kuji[5] = '吉'; $msg[0] = '今日の運勢は最高。
ただし、油断は大敵。'; $msg[1] = '運勢はまだまだ上昇中。
その調子で努力を続けよ。'; $msg[2] = 'これから徐々に上向く気配。
立ち止まるな。'; $msg[3] = '努力がもっと必要。
頑張れ。'; $msg[4] = '運気はこれから上向く。
小さな事からまず始めよ。'; $msg[5] = '運気の上昇も下降もこれからの努力次第。
足元に注意。'; # 乱数を発生 srand(time ^ ($$ + ($$ << 15))); $data = int(rand($#kuji +1)); $col[0] = ''; $col[1] = ''; $col[2] = ''; $col[3] = 'ライムグリーン'; $col[4] = 'ピンク'; $col[5] = ''; $col[6] = ''; $col[7] = ''; $col[8] = ''; $col[9] = ''; $col[10] = 'オレンジ'; $col[11] = ''; $col[12] = 'グレー'; $col[13] = '水色'; $col[14] = 'モスグリーン'; # 乱数を発生 srand(time ^ ($$ + ($$ << 15))); $data2 = int(rand($#col +1)); # 結果 &header; print <<"EOM";



$kuji[$data]

$msg[$data]





- 今日のラッキー色 : $col[$data2] -


EOM exit; }