#!/usr/bin/perl ## -------------------------------------------------------------------------- ## MIDNIGHT FOX CHAT v1.31 ## Copyright(C) 1997-99 Kent Web (1999/12/14) ## E-MAIL webmaster@kent-web.com ## HomePage http://www.kent-web.com/ $ver = 'FOX v1.31'; # バージョン情報(修正不要) ## ----[注意事項ほか]-------------------------------------------------------- ## ・このスクリプトはフリーソフトです。このスクリプトを使用したいかなる損害に ## 対して作者は責任を負いません。 ## ・設置に関する質問は直接メールではお受けできませんので「サポート掲示板」 ## へお願いいたします。 ## -------------------------------------------------------------------------- #============# # 設定項目 # #============# # jcode.plが同一ディレクトリにある場合 require './jcode.pl'; # タイトル名 $title = " 雁宿小学校 インターネットクラブ CHAT"; # bodyタグ $backgif = ""; # 壁紙 $bgcolor = "#FFFFEE"; # 背景色 $text = "#006400"; # 文字色 $link = "#0000FF"; # リンク色(未訪問) $vlink = "#800080"; # リンク色(訪問済) $alink = "#FF0000"; # リンク色(訪問中) # 戻り先のURL (index.htmlなど) $homepage = 'http://www.kariyado-e.ed.jp/'; # 最大記事数 $max = 300; # リロード時間の選択秒数 @reload = (0,20,30,45,60); # リロード時間の初期値 $re_sec = 60; # ↓上下のID/PA配列はSSコンマで区切っていくつでも指定可。 @userid = ('kari2','guest'); # ユーザID @userpwd = ('tam00039','abguest'); # ユーザPASSWORD # ↑上下のID/PASS配列は必ずペアで指定する # 文字色を指定(必ず偶数で。上下の配列はペアで) @COLORS = ('0000FF','DF0000','008040','800000','C100C1','FF80C0','FF8040','000080'); @IROIRO = ('青','赤','みどり','茶','紫','ピンク','オレンジ','あい色'); # タイトルGIF画像 $titletag = ''; # BACKのGIF画像 $backtag = ''; # タグの許可 (0=no 1=yes) $tagkey = 0; # methodの形式 (POST or GET) $method = 'POST'; # ポインタの形状(ログ表示部で「名前」の前につく) $pointer = "★"; # スクリプトファイル名 $script = "karifox.cgi"; # ログファイル名 $logfile = "./fox1.log"; # 参加者表示ファイル名 $memfile = "./member.dat"; # ロックファイル機構 (0=no 1=symlink 2=open) $lockkey = 0; # ロックファイル名 $lockfile = "./fox.lock"; # 入退室案内名 $master = "MASTER"; # 入室メッセージ $in_msg = "さん、いらっしゃい。"; # 退室メッセージ $out_msg = "さん、さようなら。"; # 入退室メッセージの色 $rep_color = "#808080"; # 入室時にIPアドレスを表示 $host_view = 1; # Chat Managerの使用 (0=no 1=yes) $manager = 0; # Chat Managerを指定 $chatmgr = "./chatmgr.cgi"; # IPアドレスによるアクセス拒否 (0=no 1=yes) $denykey = 0; # 上記の場合の拒否アドレスのログ $denyfile = "./deny.dat"; # 発言ランキング (0=no 1=yes) $rankkey = 0; # 発言ランクファイル $rankfile = "./rank.dat"; # 発言ランクログ保存日数 $limit = 7; # かお文字を定義 $faces[0] = ""; $faces[1] = "(^_^)"; $faces[2] = "(^_^;)"; $faces[3] = "(*^^*)"; $faces[4] = "(;_;)"; $faces[5] = "(ーー;"; $faces[6] = " m(_ _)m"; $faces[7] = "(・_・)"; $faces[8] = "(^^)/~~"; $faces[9] = "(@_@)"; $faces[10] = "\(^O^)/"; $faces[11] = "(?_?)"; #============# # 設定完了 # #============# # IPアドレスを取得 $host = $ENV{'REMOTE_ADDR'}; if ($backgif) { $body = ""; } else { $body = ""; } # IPアドレス拒否機能 if ($denykey) { &deny; } &decode; if (!$buffer) { ✓ } if ($mode eq 'pass_chk') { &pass_chk(in); } if ($mode eq 'form') { &form1; } if ($mode eq 'into') { &form2; } if ($com && $mode eq 'msg') { ®ist; } if ($mode eq 'bye') { &byebye; } &log_view; ## --- パスワード画面 sub check { &get_cookie(pwd); &header; print <<"HTML";


ネットワークパスワードの入力
認証情報を入力してください。

リソ\ース: $title
ユーザ名
パスワード
このパスワードを保存する
HTML exit; } ## --- パスワードエラー処理 sub pass_err { &header; print <<"HTML";

Authorization Required

This server could not verify that you are authorized to access the document you requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.

HTML exit; } ## --- ID/PASSチェック処理 sub pass_chk { # フォーム入力のチェック if ($uid eq "" || $upw eq "") { &error("ID またはパスワードが入力されていません。"); } # ID/PASSをチェックする $pflag = 0; foreach (0 .. $#userid) { if ($uid eq "$userid[$_]" && $upw eq "$userpwd[$_]") { $pflag = 1; last; } } # 該当なしの場合はエラー処理 if ($pflag == 0) { &pass_err; } # ID/PASS情報をクッキー格納 if ($FORM{'chk'} eq 'on') { &set_cookie(pwd); } # フレームを出力 if ($_[0] eq 'in') { # クッキーを取得 &get_cookie; # クッキーにリロード時間がない場合は初期値 if ($c_retime eq "") { $c_retime = "$re_sec"; } &header; print "\n"; print "\n"; print "\n"; print "\n<body>\n"; print "<h3>フレーム非対応のブラウザの方は利用できません。</h3>\n"; print "</body>\n\n"; exit; } } ## --- HTMLのヘッダー sub header { print "Content-type: text/html\n\n"; print "\n\n"; print "\n"; print "$title\n"; } ## --- フォーム1 sub form1 { # クッキーを取得 &get_cookie; # HTMLを出力 &header; print <<"EOM"; $body $backtag

$titletag

\n"; print "
おなまえ
Eメール
自動リロード
文字色を選んでください。
\n"; if ($c_color eq "") { $c_color = "$COLORS[0]"; } $i = 0; $key = @COLORS; $key = $key/2 + 1; foreach (0 .. $#COLORS) { $i++; if ($i == $key) { print "
"; } if ($c_color eq "$COLORS[$_]") { print ""; print "\n"; } else { print ""; print "\n"; } } print "
\n"; print "\n\n"; exit; } ## --- フォーム2 sub form2 { ®ist('into'); # クッキーを提供 &set_cookie; # MSIEの場合フォームの長さを調整 if ($ENV{'HTTP_USER_AGENT'} =~ /MSIE/) { $width = 90; } else { $width = 65; } # 以下のJavaScript(発言コメントの自動消去機能)は # ゆいちゃっと(http://www.a-web.co.jp/~yui/)から移植しました。 print "Content-type: text/html\n\n"; print <<"HTML"; CHAT ROOM $body
\n"; print "
名前$name
発言
かお文字 \n"; print "文字色 \n"; print " リロード時間 \n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "発言自動消去
\n"; if ($manager) { print "[管理用]\n"; } if ($rankkey) { print "[発言ランキング]\n"; } print "\n"; exit; } ## --- 記事表示部 sub log_view { # ID/PASS をチェック &pass_chk; open(LOG,"$logfile") || &error("Can't open $logfile"); @lines = ; close(LOG); print "Content-type: text/html\n\n"; print "\n\n"; print "\n"; if ($retime != 0) { print "\n"; } ## 参加者表示(ゆいちゃっと式) &sanka; $num = @sanka3; print "\n$body\n"; print "\n"; print "
参加者($num):@sanka3リロード設定\: \n"; if ($retime == 0) { print "手動モード"; } else { print "$retime秒"; } print "
\n"; foreach (@lines) { ($date,$name,$email,$comment,$color) = split(/<>/, $_); print "
\n"; print "$name > $comment \n"; print "($date)
\n"; } # 著作権を表示(削除はしないで下さい) print "
\n"; print "- Midnight Fox -\n"; print "
\n"; print "\n\n"; exit; } ## --- ログ書き込み処理 sub regist { # ID/PASS をチェック &pass_chk; # ファイルロック if ($lockkey == 1) { &lock1; } elsif ($lockkey == 2) { &lock2; } if ($_[0] eq 'into') { if ($host_view) { $com = "$name$in_msg <$host>"; } else { $com = "$name$in_msg"; } $n_email = ""; $n_name = "$master"; $n_color = "$rep_color"; } elsif ($_[0] eq 'bye') { $com = "$name$out_msg"; $n_email = ""; $n_name = "$master"; $n_color = "$rep_color"; } else { if ($email eq "") { $n_name = "$pointer $name"; } else { $n_name = "$pointer $name"; } $n_email = $email; $n_color = $color; # 発言ランキング処理 if ($rankkey) { &ranking; } } # ログを開く open(IN,"$logfile") || &error("Can't open $logfile"); @lines = ; close(IN); @new = (); ## 以下の先頭の # を10個外すと、clear と入力することで自分の記事を削除することができます # if ($com eq 'clear'){ # foreach $line (@lines) { # $flag = 0; # ($da,$na,$em,$com,$col,$ho) = split(/<>/,$line); # if ($host eq "$ho") { $flag = 1; } # if ($flag == 0) { push(@new,$line); } # } # $com = "(^-^)v"; # } else { for($i=0;$i<$max-1;$i++) { push (@new,$lines[$i]); } # } $com =~ s/\(\*\^\^\*\)/\(\*<\/font>\^\^\*<\/font>\)/g; # ログをフォーマット unshift (@new,"$date<>$n_name<>$n_email<>$com<>$n_color<>$host<>\n"); open(OUT,">$logfile") || &error("Can't write $logfile"); print OUT @new; close(OUT); # ロック解除 if (-e $lockfile) { unlink($lockfile); } } ## --- フォームからのデータ処理 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; # タグ処理 if ($tagkey == 0) { $value =~ s//>/g; } else { $value =~ s/<>/<>/g; $value =~ s///g; } $value =~ s/\r|\n//g; $FORM{$name} = $value; } $name = $FORM{'name'}; $com = $FORM{'comment'}; $email = $FORM{'email'}; $mode = $FORM{'mode'}; $retime = $FORM{'retime'}; $color = $FORM{'color'}; $face = $FORM{'face'}; $uid = $FORM{'uid'}; $uid =~ s/\s*//g; $upw = $FORM{'upw'}; $upw =~ s/\s*//g; if ($face ne "") { $com = "$com $face"; } if ($name eq "") { $name = $host; } # 時間を取得 $ENV{'TZ'} = "JST-9"; $times = time; ($sec,$min,$hour,$mday,$mon) = localtime($times); $min = "0$min" if ($min < 10); $mon++; # 日時をフォーマット $date = "$mon/$mday\-$hour:$min:$sec"; } ## --- 退室処理 sub byebye { ®ist('bye'); &header; print <<"HTML"; $body

$nameさん、ご利用ありがとうございました。

HTML exit; } ## --- クッキーの発行 sub set_cookie { # クッキーIDを定義 if ($_[0] eq "pwd") { $cook_id = "fox_in"; } else { $cook_id = "fox_chat"; } ($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg) = gmtime(time + 60*24*60*60); $yearg += 1900; if ($secg < 10) { $secg = "0$secg"; } if ($ming < 10) { $ming = "0$ming"; } if ($hourg < 10) { $hourg = "0$hourg"; } if ($mdayg < 10) { $mdayg = "0$mdayg"; } $month = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug', 'Sep','Oct','Nov','Dec') [$mong]; $youbi = ('Sunday','Monday','Tuesday','Wednesday','Thursday', 'Friday','Saturday') [$wdayg]; $date_gmt = "$youbi, $mdayg\-$month\-$yearg $hourg:$ming:$secg GMT"; $cook = "name\:$name\,email\:$email\,color\:$color\,retime\:$retime\,uid\:$uid\,upw\:$upw"; print "Set-Cookie: $cook_id=$cook; expires=$date_gmt\n"; } ## --- クッキーを取得 sub get_cookie { # クッキーIDを定義 if ($_[0] eq "pwd") { $cook_id = "fox_in"; } else { $cook_id = "fox_chat"; } @pairs = split(/;/, $ENV{'HTTP_COOKIE'}); foreach $pair (@pairs) { local($name, $value) = split(/=/, $pair); $name =~ s/ //g; $DUMMY{$name} = $value; } @pairs = split(/,/,$DUMMY{$cook_id}); foreach $pair (@pairs) { local($name, $value) = split(/:/, $pair); $COOKIE{$name} = $value; } $c_name = $COOKIE{'name'}; $c_email = $COOKIE{'email'}; $c_color = $COOKIE{'color'}; $c_retime = $COOKIE{'retime'}; $c_id = $COOKIE{'uid'}; $c_pw = $COOKIE{'upw'}; if ($FORM{'name'}) { $c_name = $FORM{'name'}; } if ($FORM{'email'}) { $c_email = $FORM{'email'}; } if ($FORM{'color'}) { $c_color = $FORM{'color'}; } if ($FORM{'retime'}) { $c_retime = $FORM{'retime'}; } if ($FORM{'uid'}) { $c_id = $FORM{'uid'}; } if ($FORM{'upw'}) { $c_pw = $FORM{'upw'}; } } ## --- エラー表示処理 sub error { if (-e $lockfile) { unlink($lockfile); } &header; print "$body\n"; print "

ERROR !

\n"; print "

$_[0]\n"; print "


\n"; print "\n\n"; exit; } ## --- ロックファイル(symlink関数) sub lock1 { local($retry) = 5; while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &error('LOCK is BUSY'); } sleep(1); } } ## --- ロックファイル(open関数) sub lock2 { $lockflag = 0; foreach (1 .. 5) { if (-e $lockfile) { sleep(1); } else { $lockflag = 1; open(LOCK,">$lockfile"); close(LOCK); last; } } if ($lockflag == 0) { &error("LOCK is BUSY"); } } ## 以下の参加者表示機能は ##「ゆいちゃっと(http://www.a-web.co.jp/~yui/)」から移植しました。 sub sanka { open(LOG,"$memfile") || &error("Can't open $memfile"); seek(LOG,0,0); @sanka=; close(LOG); $flag=1; foreach $line (@sanka) { ($timerec,$handle,$host2,$dmy) = split(/<>/, $line); if ($times-60 > $timerec) { $line = ''; next; } # ホスト名が同一の場合、時間と名前を最新のものにする。 if (($host2 eq "$host") && $flag) { $line = "$times<>$name<>$host<>d\n"; $flag = 0; $handle = $name; $handle =~ s/☆/★/g; } push (@sanka3, "$handle☆") if ($handle ne $host2); } # 新しい参加者を加える if ($flag) { push(@sanka,"$times<>$name<>$host<>d\n"); $name =~ s/☆/★/g; push (@sanka3, "$name☆") if ($name ne $host); } undef(@sanka) if ($com eq 'sanka'); open(LOG,">$memfile") || &error("Can't write $memfile"); eval 'flock(LOG,2);'; seek(LOG,0,0); print LOG @sanka; eval 'flock(LOG,8);'; close(LOG); } ## --- IPアドレスによるアクセス拒否 sub deny { open(IN,"$denyfile") || &error("Can't open $denyfile"); @lines = ; close(IN); $dflag = 0; foreach $line (@lines) { $line =~ s/\n//g; if ($host =~ /$line/) { $dflag = 1; last; } } if ($dflag) { &error("申\し訳ありませんが、現在ご利用できません。"); } } ## --- 発言ランキング処理 sub ranking { open(IN,"$rankfile") || &error("Can't open $rankfile"); @ranks = ; close(IN); $rflag=0; foreach $rline (@ranks) { ($r_name,$r_kaisu,$r_time) = split(/<>/,$rline); if ($times - $r_time > $limit*24*60*60) { next; } if ($r_name eq "$name") { $rflag=1; $r_kaisu++; $rline = "$r_name<>$r_kaisu<>$times<>\n"; } push(@r_new,"$rline"); } if ($rflag == 0) { unshift(@r_new,"$name<>1<>$times<>\n"); } open(OUT,">$rankfile") || &error("Can't write $rankfile"); print OUT @r_new; close(OUT); }