#!/usr/bin/perl #!/usr/bin/perl -w #use strict; #no strict 'vars'; #------------------------------- # chat.cgi v2.32 (ShiftJIS) # 2001.11. 9 MIYAMORI Yoshimasa # (kan_ta@amcsys.com) #------------------------------- require '../../jcode.pl'; $charSep = ','; $codeSjis = 'sjis'; $codeEuc = 'euc'; $myOut = $codeSjis; #$myOut = $codeEuc; $myFileMode = '666'; $myLogLimit = 400; $myLogDisp = 40; $myLogCompact = 20; $myRomTime = 1800; $myMailto = 'kan_ta@amcsys.com'; $myTitle = 'ちゃっとぺーじ♪'; $myUrl = '/cgi-bin/sample/chat/chat.cgi'; $myUrlHtml = '/sample/chat/chat.html'; $errFile = '../../../sample/chat/chat.err'; $lockFile = '../../../sample/chat/chat.lck'; $logFile = '../../../sample/chat/chat.log'; $tmpFile = '../../../sample/chat/chat.tmp'; $romFile = '../../../sample/chat/chat.rom'; &main; exit; sub dispLog { local($rom, $romTime, $lastName) = @_; local($s); if ($romTime < 0) { $s = '退室'; } else { $s = '退室'; } print <<"EndOfFile"; Content-type: text/html; charset=$myCharSet\n $myTitle フレーム版 | iモード 『$myTitle』 お名前: 本文: 入室 $s ( $rom) EndOfFile &dispLogSub($myLogDisp, 0); print '', "\n"; } # フレーム用の表示. $time ごとに更新. sub dispFrameLog { local($rom, $time) = @_; print <<"EndOfFile"; Content-type: text/html; charset=$myCharSet\n $myTitle ( $rom) EndOfFile &dispLogSub($myLogDisp, 0); print '', "\n"; } # モバイル端末用の表示. シフトJISで出力. sub dispCompactLog { local($lastName) = @_; local($s1, $s2, $s3, $s4, $s5, $s6, $s7, $s8); $s1 = &toSjis($lastName, $myOut); $s2 = &toSjis($myTitle, $myOut); $s3 = &toSjis('名前', $myOut); $s4 = &toSjis('本文', $myOut); $s5 = &toSjis('漢字', $myOut); $s6 = &toSjis('送る', $myOut); $s7 = &toSjis('↑', $myOut); $s8 = &toSjis('↓', $myOut); print <<"EndOfFile"; Content-type: text/html; charset=Shift_JIS\n $s2 $s2 $s3 $s4 1.$s7,2.$s8 EndOfFile &dispLogSub($myLogCompact, 1); print <<"EndOfFile"; 1.$s7,2.$s8 EndOfFile } sub dispLogSub { local($num, $compact) = @_; local($i, $name, $body, $date, $host); unless (-f $logFile) { open(FILE, ">$logFile") || &exitCgi('error: dispLogSub().'); close FILE; } if ($myOut eq $codeEuc) { open(FILE, "<$logFile") || &exitCgi('error: dispLogSub().'); $i = 0; if ($compact) { while () { ($name, $body, $date, $host) = split($charSep, $_); # $date =~ s/.*\((.*\(.*\).*)\).*\n/$1/; # v2.1までのログを表示する時. $date =~ s/.*(..):(..):(..).*/\($1:$2\)/; print &toSjis(join('', $name, ':', $body, $date, '', "\n"), $myOut); $i++; last if ($i >= $num); } } else { while () { ($name, $body, $date, $host) = split($charSep, $_); # $date =~ s/.*\((.*\(.*\).*)\).*\n/$1/; printf("%s: %s (%s)\n", $name, $body, $date, substr($host, 0, 4)); $i++; last if ($i >= $num); } } close FILE; } else { open(FILE, "<$logFile") || &exitCgi('error: dispLogSub().'); open(TMP, ">$tmpFile") || &exitCgi('error: dispLogSub().'); $i = 0; while () { print TMP &toEuc($_, $myOut); $i++; last if ($i >= $num); } close FILE; close TMP; open(FILE, "<$tmpFile") || &exitCgi('error: dispLogSub().'); if ($compact) { while () { ($name, $body, $date, $host) = split($charSep, $_); # $date =~ s/.*\((.*\(.*\).*)\).*\n/$1/; $date =~ s/.*(..):(..):(..).*/\($1:$2\)/; print &toSjis(join('', $name, ':', $body, $date, '', "\n"), $codeEuc); } } else { while () { ($name, $body, $date, $host) = split($charSep, $_); # $date =~ s/.*\((.*\(.*\).*)\).*\n/$1/; print &toSjis(sprintf("%s: %s (%s)\n", $name, $body, $date, substr($host, 0, 4)), $codeEuc); } } close FILE; unlink $tmpFile; } } sub putLog { local($s, $i); $in{'chatName'} = "???" unless ($in{'chatName'}); $s = join($charSep, $in{'chatName'}, $in{'chatBody'}, &getDate, $ENV{'REMOTE_HOST'}); sleep(2) if (-f $tmpFile); open(TMP, ">$tmpFile") || &exitCgi('error: putLog().'); print TMP $s, "\n"; if (-f $logFile) { open(FILE, "<$logFile") || &exitCgi('error: putLog().'); $i = 1; while () { print TMP $_; $i++; last if ($i >= $myLogLimit); } close FILE; } close TMP; rename($tmpFile, $logFile); chmod oct($myFileMode), $logFile; } sub getDate { local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); local($wday2); ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = gmtime(time + 9 * 3600); $hour = "0$hour" if ($hour < 10); $min = "0$min" if ($min < 10); $sec = "0$sec" if ($sec < 10); if ($year > 99) { $year = $year + 1900; } $mon = $mon + 1; $mon = "0$mon" if ($mon < 10); $mday = "0$mday" if ($mday < 10); $wday2 = ('日','月','火','水','木','金','土')[$wday]; join('', $year,'年',$mon,'月',$mday,'日','(',$wday2,') ',$hour,':',$min,':',$sec); } # $txt のコード判別. # 'jis', 'sjis', 'euc', 'binary', undef. sub getCode { local($txt) = @_; &jcode'getcode(*txt); } # $txt をシフトJISに. sub toSjis { local($txt, $icode) = @_; &jcode'convert(*txt, 'sjis', $icode, 'z'); $txt; } # $txt を EUCに. sub toEuc { local($txt, $icode) = @_; &jcode'convert(*txt, 'euc', $icode, 'z'); $txt; } # &parseQry(*qry) で 連想配列 $qry{'chatName'} などに値をセットする. # $myIn に $qry{'chatCode'} から得た元の文字コードをセットする. sub parseQry { local(*qry) = @_; local(@tmpArray, $key, $val); local($s, $i); if ($ENV{'REQUEST_METHOD'} eq 'POST') { &exitCgi('error: parseQry().') if (1024 < $ENV{'CONTENT_LENGTH'}); # 1Kに制限. read(STDIN, $s, $ENV{'CONTENT_LENGTH'}); } else { $s = $ENV{'QUERY_STRING'}; } @tmpArray = split(/&/, $s); foreach $i (0 .. $#tmpArray) { $tmpArray[$i] =~ s/\+/ /g; ($key, $val) = split(/=/,$tmpArray[$i], 2); $key =~ s/%(..)/pack('C',hex($1))/ge; $val =~ s/%(..)/pack('C',hex($1))/ge; if (defined($qry{$key})) { # 複数選択のlistboxなどの時. $qry{$key} = join("\0", $qry{$key}, $val); } else { $qry{$key} = $val; } $myIn = &getCode($val) if ($key eq 'chatCode'); } foreach $key (keys(%qry)) { $qry{$key} = &toEuc($qry{$key}, $myIn); $qry{$key} =~ s/\r\n//go; $qry{$key} =~ s/\r//go; $qry{$key} =~ s/"/"/go; $qry{$key} =~ s/,/,/go; $qry{$key} =~ s/</go; $qry{$key} =~ s/>/>/go; } if ($myOut eq $codeSjis) { foreach $key (keys(%qry)) { $qry{$key} = &toSjis($qry{$key}, 'euc'); } } } # エラーメッセージを表示し, ログを残して終了. sub exitCgi { local($text) = @_; local($i); print <<"EndOfFile"; Content-type: text/html\n $myTitle 作業中にエラーが発生しました. EndOfFile open(TMP, ">$tmpFile"); print TMP &getDate, "\n"; print TMP $text, "\n"; if (-f $errFile) { open(FILE, "<$errFile"); $i = 0; while () { print TMP $_; $i++; last if ($i >= 1000); } close FILE; } close TMP; rename($tmpFile, $errFile); chmod oct($myFileMode), $errFile; exit; } sub chkRom { local($time, $name); local($now, $buf, $ret, $s, $t, $n, $line); $now = time; $s = ''; $s = ($now + $in{'romTime'}).$charSep.$in{'chatName'}."\n" if ($in{'romTime'} > 0); $t = &toEuc($in{'chatName'}, $myOut); unless (-f $romFile) { open(FILE, ">$romFile") || &exitCgi('error: chkRom().'); close FILE; } open(FILE, "<$romFile") || &exitCgi('error: chkRom().'); $buf = $ret = ''; $n = 0; while () { $line = $_; ($time, $name) = split($charSep, $line); chop($name); if (&toEuc($name, $myOut) eq $t) { $n = 1; if ($s ne '') { $buf .= $s; $ret .= $name.' '; } } else { if ($time > $now) { $buf .= $line; $ret .= $name . ' '; } } } close FILE; open(FILE, ">$romFile") || &exitCgi('error: chkRom().'); print FILE $buf; unless ($n) { if ($in{'romTime'} > 0) { print FILE $s; $ret .= $in{'chatName'}.' '; } } close FILE; $ret; } sub main { local(%in); local($dummy, $rom, $n); if ($myOut eq $codeSjis) { $myCharSet = 'Shift_JIS'; } else { $myCharSet = 'EUC-JP'; } open(LOCK, ">$lockFile") || &exitCgi('error: main().'); flock(LOCK, 2); &parseQry(*in); &putLog if ($in{'chatBody'}); $rom = &chkRom; if ($ENV{'QUERY_STRING'} =~ /^chatFrame/) { ($dummy, $n) = split(/=/, $ENV{'QUERY_STRING'}, 2); $n = 30 if ($n < 30); &dispFrameLog($rom, $n); } elsif ($in{'chatFrame'} ne '') { $n = $in{'chatFrame'}; $n = 30 if ($n < 30); &dispFrameLog($rom, $n); } elsif ($in{'chatCompact'}) { &dispCompactLog($in{'chatName'}); } else { &dispLog($rom, $in{'romTime'}, $in{'chatName'}); } undef $ENV{'QUERY_STRING'}; undef $ENV{'REMOTE_HOST'}; flock(LOCK, 8); close LOCK; }
1.$s7,2.$s8 EndOfFile &dispLogSub($myLogCompact, 1); print <<"EndOfFile"; 1.$s7,2.$s8
作業中にエラーが発生しました.