#!/usr/bin/perl
#Perlのパスを指定
#普通は、『#!/usr/bin/perl』or『#!/usr/local/bin/perl』を指定
#プロバイダによっては、『#!/usr/local/bin/perl5』の場合もあり。
###############################################
#このscriptの著作権は・・・
#HPサービス(hp@bird.to・mkc@intacc.ne.jp)に帰属しています。
#よって、改竄する事は許可しますが、著作権の表示は削除しないで下さい。
#また、このscriptによる如何なる損害も賠償しませんので・・・
#予め、ご了承下さい。
#尚、バグ情報などは、HPサービス(hp@bird.to)まで
#お知らせ頂けると有難いです。
#また、利用にあたっては、HPサービス(http://hp.bird.to/)に従って下さい。
####################使用方法######################
#一番上のPerlのパスを合わせて転送し、パーミッションを設定すれば・・・
#それで、使えるようになります。
#このCGIのカスタマイズは、ほとんどインターネット上で出来るように
#作ってありますので、ファイル内容を、特に変更する必要はありません。
####################変数設定######################
#(★☆)は、変更可能部分(よく分からない人は、変更しない事!!)
#(★)は、変更しない方がいい部分
#(☆)は、変更した方がいい部分
# 管理人専用コマンドの暗証番号(秘密の暗号に書き換えて下さい)(☆)
my $secret='4321';
# カスタマイズ用ファイル(★☆)
#注:access2_list.cgiのカスタマイズ用ファイル名と同じにする事。
my $custom_file='./DATA/access2_custom.cgi';
# データファイル名(★☆)
#注:access2_list.cgiのデータファイル名と同じにする事。
my $data_file = './DATA/access2_today.cgi';
# 昨日のデータファイル名(★☆)
#注:access2_list.cgiのデータファイル名と同じにする事。
my $yesterday_file = './DATA/access2_yesterday.cgi';
# 過去のデータファイル名(★☆)
#注:access2_list.cgiのデータファイル名と同じにする事。
my $total_file = './DATA/access2_total.cgi';
# HP・URLデータファイル名(★☆)
#注:access2_list.cgiのデータファイル名と同じにする事。
my $hpurl_file = './DATA/access2_hpurl.cgi';
#ログデータファイル名(★☆)
#注:access2_list.cgiのデータファイル名と同じにする事。
my $log_file = './DATA/access2_log.cgi';
# タイトルの名前(★☆)
my $html_title = 'アクセス解析SP';
#homeのURL(自分のHPのURLを記入する)(★☆)
my $home_url = 'http://hp.bird.to/info/access.html';
#あなたのHPドメイン(このURLを含むアクセス元はMy HPと表示される)(★☆)
my $my_url = '';
#解析結果をメール送信する(する場合は=1、しない場合は=0)(★☆)
my $need_mail = 0;
#あなたのメールアドレス(解析結果をメール送信しない場合は不要)(☆)
my $my_address= '';
#sendmailのパス(解析結果をメール送信しない場合は不要)(☆)
my $sendmail= '/usr/lib/sendmail';
#sujbectに記入する題名(解析結果をメール送信しない場合は不要)(★☆)
my $default_subject= 'アクセス解析報告';
#記録ログ数(デフォルトは10日間)(★☆)
my $log_max = 10;
#リンク元データ表で省略するカウント数(★☆)
my $display_limit = 0;
#ログレポート送信時間(デフォルトは、正午12時)(★☆)
my $time_adjustment=12;
# アクセス受付間隔(デフォルトでは、1時間でアクセスを受け付ける)(★☆)
my $wait_time=60*60*1;
#フッターに挿入するタグ(★☆)
my $hooter ="HOME";
#グラフの色(★☆)
my $listblock='./IMAGE/listblock/block0.gif';
#出力画像(★☆)
my $access_image='./IMAGE/listblock/block6.gif';
#バックの色(★☆)
my $bgcolor='black';
#バックのイラスト(★☆)
my $background='./IMAGE/background/night.gif';
#文字の色(★☆)
my $textcolor='white';
#リンクの色(★☆)
my $linkcolor ='red';
#一度訪れたリンクの色(★☆)
my $vlinkcolor='red';
#項目色(★☆)
my $subcolor='blue';
#項目背景色(★☆)
my $trcolor='lightgoldenrodyellow';
#レポート送信間隔・日付変更間隔(★)
my $limit_time=60*60*24;
#perlのバージョンを指定(★)
require 5.001;
#jcode.plのパスを指定(★)
require "./jcode.pl";
#custom.plのパスを指定(★)
require "./custom_access.pl";
# 排他制御として使用するディレクトリ名(★)
my $lockname='./DATA/access2lock';
#現在time(★)
my $now_time=time();
# 排他制御使用関数(★)
my $expire = 3*60; # 最大排他制御時間( sec )
my $num_retry = 5; # 最大再試行回数
my $retry_time = 1; # 排他制御待ち時間( sec )
#sendmail に付加するオプション(★)
my $mailoption= ' -t';
#エラーメール対策オプション(★)
my $envelope= '-f ';
##########ここより先は、Perlの知識が必要です!!##########
##########よく分からない人は、立ち入るべからず##########
if($ENV{'QUERY_STRING'} ne ''){
my $temp;
($temp,$referer)=split(/=/,$ENV{'QUERY_STRING'});
}
else{
$referer = $ENV{'HTTP_REFERER'};#呼び出しサイト
}
$remote_host=$ENV{'REMOTE_HOST'};#クライアントのホスト名
$remote_host=$ENV{'REMOTE_ADDR'} if($remote_host eq '');
$user_agent=$ENV{'HTTP_USER_AGENT'};#クライアントのブラウザ名
if(defined ($dlock_id=&LockOn($lockname))){
my @copy_custom=($html_title,$home_url,$bgcolor,$background,$textcolor,$linkcolor,$vlinkcolor,$subcolor,$trcolor,$listblock,$log_max,$secret,$access_image,$display_limit,$my_url,$need_mail,$my_address,$default_subject,$sendmail,$hooter);
my @custom=&custom_open($custom_file,@copy_custom);#カスタマイズ類を取得
foreach(@custom){
$_=~s/,/,/g;
}
($html_title,$home_url,$bgcolor,$background,$textcolor,$linkcolor,$vlinkcolor,$subcolor,$trcolor,$listblock,$log_max,$secret,$access_image,$display_limit,$my_url,$need_mail,$my_address,$default_subject,$sendmail,$hooter)=@custom;#カスタマイズ類を設定
print "Content-type: image/gif\n\n";
if(open(IMG, "$access_image")){
print $_ while (
);
close(IMG);
}#とりあえず出力
&data_open;
if($deadline_time<$now_time){
&log_report;
}
else{
&log_open;
&data_save if($reload_check==0);
&log_save if($reload_check==0);
}
&LockOff($dlock_id);
}#排他制御終了
else{
my @copy_custom=($html_title,$home_url,$bgcolor,$background,$textcolor,$linkcolor,$vlinkcolor,$subcolor,$trcolor,$listblock,$log_max,$secret,$access_image,$display_limit,$my_url,$need_mail,$my_address,$default_subject,$sendmail,$hooter);
my @custom=&custom_open($custom_file,@copy_custom);#カスタマイズ類を取得
foreach(@custom){
$_=~s/,/,/g;
}
($html_title,$home_url,$bgcolor,$background,$textcolor,$linkcolor,$vlinkcolor,$subcolor,$trcolor,$listblock,$log_max,$secret,$access_image,$display_limit,$my_url,$need_mail,$my_address,$default_subject,$sendmail,$hooter)=@custom;#カスタマイズ類を設定
print "Content-type: image/gif\n\n";
if(open(IMG, "$access_image")){
print $_ while (
);
close(IMG);
}#とりあえず出力
}
exit 0;
####################ログを報告する####################
sub log_report{
if(open(DATA,"$hpurl_file")){
my @line = ;
close(DATA);
for($i=0; $i<@line; $i++){
chomp($line[$i]);
my($url,$hp_name) = split(/,/,$line[$i]);
$hp_names{$url}=$hp_name;
}
}
my @referers=keys %referers;
$all_access=@referers;#総訪問者数
foreach(@referers){
my ($sec,$min,$hour) = localtime($_);
$hour_nums{$hour}++;#時間帯別訪問者数
$referer_nums{$referers{$_}}++;#リンク先別訪問者数
}
foreach(0..23){
$hour_report.=$_.'時:'.$hour_nums{$_}."\n";
}
my @referer_ranks=sort { $referer_nums{$b}<=>$referer_nums{$a} }keys %referer_nums;
foreach(@referer_ranks){
if($referer_nums{$_}>$display_limit){
my $hp_name=$_;
$hp_name=$hp_names{$_} if($hp_names{$_} ne '');
$referer_report.=$hp_name.':'.$referer_nums{$_}."\n";
}
}
$report="昨日のアクセス統計をご報告します。\n\n";
$report.="総訪問者数は、$all_access人でした。\n\n";
$report.="時間帯別のアクセス数は下記の通りです。\n\n";
$report.="$hour_report\n";
$report.="リンク先別のアクセス数は下記の通りです。\n\n";
$report.="$referer_report\n";
if($need_mail==1){
if(mailto($to, $cc,$email,$subject,$report)==0){
$error_code='サーバの調子が悪いようです';
}
}#解析レポートを送信するが1の時だけ、メールを送る。
if(open(TOTAL, "$total_file")){
my @line = ;
close(TOTAL);
unshift(@line,"$deadline_time,$all_access\n");
#データをデータリストの先頭に記録します
splice(@line,$log_max,@line-$log_max) if(@line > $log_max);
#最大リスト数を超える分は削除します
if(open(TOTAL, ">$total_file")){
for($i=0;$i<@line;$i++){
print TOTAL "$line[$i]";
}
close(TOTAL);
}
}#総訪問者数を保存
$deadline_time+=$limit_time;
if(open(DATA, ">$data_file")){
print DATA "$deadline_time\n";
print DATA "$referer,$now_time\n";
close(DATA);
}#本日データの初期化
if(open(YESTER, ">$yesterday_file")){
foreach(0..23){
print YESTER "$_,$hour_nums{$_}\n";
}
foreach(@referer_ranks){
print YESTER "$_,$referer_nums{$_}\n";
}
close(YESTER);
}#本日データを昨日データに格納
}
####################データ収集####################
sub data_open{
unless(-f $total_file){ open(TOTAL,">$total_file");close(TOTAL); }
unless(-f $yesterday_file){ open(YESTER,">$yesterday_file");close(YESTER); }
unless(-f $hpurl_file){ open(HPURL,">$hpurl_file");close(HPURL); }
unless(-f $data_file){
$deadline_time=int($now_time/(60*60*24))*(60*60*24)+(60*60*24)*2;#昨日と今日を書き換える、日付変更タイム
$deadline_time-=60*60*9;#日本時間
$deadline_time-=60*60*(24-$time_adjustment);#ログ報告時間の調整
open(DATA,">$data_file");
print DATA "$deadline_time\n";
close(DATA);
}
elsif(open(DATA,"$data_file")){
my @line = ;
close(DATA);
for($i=0; $i<@line; $i++){
chomp($line[$i]);
if($i==0){
$deadline_time=$line[$i];
last if($deadline_time>$now_time);
}
else{
my($referer,$last_time)=split(/,/,$line[$i]);
$referer='My HP' if($referer=~/$my_url/ && $my_url ne '');
$referers{$last_time}=$referer;
}
}
}
}
####################データセーブ####################
sub data_save{
if(open(DATA, ">>$data_file")){
#$referer='ブックマーク' if($referer eq '' || $referer eq '\'+document.referrer+\'' || $referer eq '[unknown' || $referer eq 'bookmarks' || $referer=~/file:/);
$referer='ブックマーク' unless($referer=~/http:/);
print DATA "$referer,$now_time\n";
close(DATA);
}
}
####################ログデータ収集####################
sub log_open{
unless(-f $log_file){
open(DATA,">$log_file");
close(DATA);
}
elsif(open(DATA,"$log_file")){
my @line = ;
close(DATA);
if(open(DATA, ">$log_file")){
for($i=0;$i<@line;$i++){
chomp($line[$i]);
my ($host,$agent,$last_time)=split(/,/,$line[$i]);
if($now_time-$wait_time<$last_time){
if($line[$i]=~/^\Q$remote_host,$user_agent,\E/){
$reload_check=1;
}
print DATA "$line[$i]\n";
}
}
close(DATA);
}
}
}
####################ログデータセーブ####################
sub log_save{
if(open(DATA, ">>$log_file")){
print DATA "$remote_host,$user_agent,$now_time\n";
close(DATA);
}
}
####################排他制御開始####################
# $id = LockOn(filename);
sub LockOn{
my ($filename)=@_;
# 古いディレクトリを削除
rmdir($filename) if(-d $filename && ($now_time-(stat($filename))[9])>$expire);
# 排他制御用ディレクトリ生成
my $retry;
for($retry=$num_retry; $retry>0 && mkdir($filename,0755)!=1; $retry--){
sleep($retry_time);
}
return $filename if($retry>0); # 成功
return undef; # 失敗
}
####################排他制御終了####################
# LockOff($id);
sub LockOff{
my ($filename)=@_;
rmdir ($filename) if(defined $filename);
}
####################メール送信関数####################
# mailto($to, $cc, $from, $subject, $body);
sub mailto{
my ($to, $cc, $from, $subject, $body) = @_;
my $ccline='';
$to= $my_address if(!defined $to || $to eq '');
$from= $my_address if(!defined $from || $from eq '');
$ccline= "Cc: $cc\n" if( defined $cc && $cc ne '');
$subject= $default_subject if(!defined $subject || $subject eq '');
# とほほのWWW - wwwmail.cgi 方式の body変換
$body =~ s/(^|\n)\.(\n|$)/$1. $2/g;
$body =~ s/(^|\n)\.(\n|$)/$1. $2/g;
$body=::jcode::jis($body);
my $mailhead = <