#!/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 = <