#! /usr/local/bin/perl
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#
# ☆ Sextans 0.15 ☆
#
# kz island (keiko)
# http://www.kz-island.net/
#
#
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
#
# ◆必要なファイル
# ・sextans.cgi[755]
# ・log.txt(ログ保存用)[666]
#
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
################### 初期設定 ここから ################################
#パスワード(アクセスログを見るときに必要)
$pass = "SHUNTEI";
#このファイル名
$file = "sextans.cgi";
#ログ保存用のファイル名
$logfile = "log.txt";
#ログを保存する日数
$tmax = 5;
#最後のログとのホスト名が同じ場合(同じ訪問者が連続してアクセスした場合)
#もう一度ログをとる(0) #ログをとらない(1)
$flag = 1;
#文字色
$color = "#333333";
#背景色
$color2 = "#FFFFFF";
#タイトル
$title = "アクセスログ";
#ロック機能を使う(使う:1、使わない:0)
#推奨「使う:1」
#「ロックエラー」と表示される場合使わないように設定してください。
$lock_use = 1;
#ロックファイル
$lockfile = "sextans.lock";
################### 初期設定 ここまで ################################
#バージョン
$version = "ver 0.15";
if($lock_use == 1){
&lock;
if (-e $lockfile) { unlink $lockfile; }
}
print "Content-type: text/html\n\n";
#------------------- 配列変数にログファイルの中身を代入 --------------
if (!open (DATA,"$logfile")) { &error(bad_file); }
@DATA = ;
close(DATA);
#------------------- フォームデコード --------------------------------
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;
$FORM{$name} = $value;
}
#------------------ ホスト名 -----------------------------------------
$host = $ENV{'REMOTE_HOST'};
$addr = $ENV{'REMOTE_ADDR'};
if ($host eq "" || $host eq "$addr") {
($p1,$p2,$p3,$p4) = split(/\./,$addr);
$temp = pack("C4",$p1,$p2,$p3,$p4);
$host = gethostbyaddr("$temp", 2);
if ($host eq "") { $host = $addr; }
}
#------------------ ブラウザとOS -------------------------------------
$agent = $ENV{'HTTP_USER_AGENT'};
for ( $agent ){
( $_ ) = split(/ *via/);
if( /Win/ && /95/) { $os = "Windows 95"; }
elsif( /Win/ && /98/) { $os = "Windows 98"; }
elsif( /Win/ && /16/) { $os = "Windows 3.1"; }
elsif( /Win/ && /NT/) { $os = "Windows NT"; }
elsif( /Mac/ && /68K/) { $os = "Mac 68K"; }
elsif( /Mac/ && /PowerPC/){ $os = "Mac PPC"; }
elsif( /Mac/ && /PPC/) { $os = "Mac PPC"; }
elsif( /X11/ ) { $os = "Unix"; }
elsif( /Linux/ ) { $os = "Linux"; }
else {$os = "Unknown";}
if( /MSIE (\d)/ ){ $brouze = "Internet Explorer $1.x";}
elsif( /Mozilla\/(\d)/ ){ $brouze = "Netscape $1.x"; }
elsif( /(\S+)\/(\d)/ ){ $brouze = "$1 $2.x";}
else {$brouze = "Unknown";}
}
#------------------ 時間の取得 -------------------------------------
$ENV{'TZ'} = "JST-9";
$time_now = time;
#------------------ リファ処理 ---------------------------------------
$ref_length = length($ENV{'QUERY_STRING'}) - 3 ;
$reffer = substr($ENV{'QUERY_STRING'},3,$ref_length) ;
#------------------- 分岐 --------------------------------------------
$query = $ENV{'QUERY_STRING'};
if ($query eq $pass) { &log_html; }
elsif ($FORM{'login'} eq "true"){
if ($FORM{'pass'} eq $pass) { &log_html; }
else { &error(bad_pass) ;}
}
elsif (substr($query,0,3) eq "log"){ &resist; }
else { &main_html }
#---------------------------------------------------------------------
##### 書き込み #####
#---------------------------------------------------------------------
sub resist {
$tmax = $tmax * 60 * 60 * 24;
$i = 0;
$count = @DATA;
#---------- 1行だけ読み込み ----------
open(DATA,"$logfile");
$before = ;
close(DATA);
#---------- 一つ前のログを比べる ----------
($time2,$reffer2,$host2,$os2,$brouze2,$d12,$d22) = split(/\,/,$before);
#---------- 書きこまないで終了 ----------
if ($host2 eq $host && $flag == 1){ exit; }
#---------- 配列に新しいログを加える ----------
$value = "$time_now\,$reffer\,$host\,$os\,$brouze\,\,\n";
unshift(@DATA,$value);
#---------- 保存期間が過ぎたものは消す ----------
foreach $line(@DATA) {
($time,$reffer,$host,$os,$brouze,$d1,$d2) = split(/\,/,$line);
if (($time_now - $tmax) > $time){
splice(@DATA,$i,$count);
last;
}
$i++;
}
#--------- 書き込み -----------
if (!open (DATA,">$logfile")) { &error(bad_file); }
print DATA @DATA;
close(DATA);
exit;
}
#---------------------------------------------------------------------
##### ログ表示 #####
#---------------------------------------------------------------------
sub log_html {
&header;
print " アクセスログ
\n";
foreach $line(@DATA) {
chop($line);
($time,$reffer,$host,$os,$brouze,$d1,$d2) = split(/\,/,$line);
#---------- 日付と時刻 ----------
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);
$year = sprintf("%02d",$year + 1900);
$month = sprintf("%02d",$mon + 1);
$mday = sprintf("%02d",$mday);
if ( substr($month,0,1) == 0 ) { $month =~ s/0/ /; }
if ( substr($mday,0,1) == 0 ) { $mday =~ s/0/ /; }
$hour = sprintf("%02d",$hour);
$min = sprintf("%02d",$min);
$sec = sprintf("%02d",$sec);
$youbi = ('日','月','火','水','木','金','土') [$wday];
$time = "$year年$month月$mday日($youbi) $hour:$min:$sec";
#---------- リファ処理 ----------
if ($reffer eq ""){ $reffer = "Direct Access or Unknown"; }
else{ $reffer =~ s/([^=^\"]|^)(http|ftp)([\w|\!\#\&\=\-\%\@\~\;\+\:\.\?\/]+)/$1$2$3<\/a>/g;
;}
#---------- ログを表示 ----------
print "
\n";
print "$time
\n";
print "リファ.....................$reffer
\n";
print "ホスト...................$host
\n";
print "OS.......................$os
\n";
print "ブラウザ...............$brouze
\n";
print "
パスワードを入力してください。
☆Sextans $version by kz island
HTML exit; } #--------------------------------------------------------------------- ##### ロック機能 ##### #--------------------------------------------------------------------- sub lock { $symlink_check = (eval { symlink("",""); },$@ eq ""); if(!$symlink_check) { $c = 0; while (-f "$lockfile") { $c++; if($c > 3) { &error('bad_retry'); } sleep(2); } } else{ local($retry) = 3; while (!symlink(".", $lockfile)) { if(--$retry <= 0) { &error('bad_retry'); } sleep(2); } } } #--------------------------------------------------------------------- ##### エラー処理 ##### #--------------------------------------------------------------------- sub error { $error = $_[0]; if ($error eq "bad_file") { $msg = "ログ保存ファイル、『$logfile』 がないか、ファイルが開けません。"; } if ($error eq "bad_pass") { $msg="パスワードが違います"; } elsif ($error eq "bad_retry") { unlink $lockfile; $msg="ロックエラー"; } &header; print<<"HTML";error
$msg