#!/usr/local/bin/perl ################################################################## # Program : count.cgi(Perl) SSI使用 $ver = 1.0; # Permission : 755 # Date_written : 2000/11/13 # Author : 良寛 # E-mail : ryokan@po.minc.ne.jp # HomePage : http://www.minc.ne.jp/~ryokan/ ################################################################## # # -----注意事項--------------------------------------------------- # (1)このスクリプトはフリーソフトです。このスクリプトを使用した # いかなる損害に対して作者は一切の責任を負いません。 # (2)設置に関する質問は質問コーナーにお願いいたします。 # ---------------------------------------------------------------- # #=== 設定(ここから)============================================= $count_data = "count.dat"; # データファイル $zikan = 5; # 同じ人がこの時間(分)内に # 訪問してもカウントしない。 $lockkey = 1; # ロックする = 1,しない = 0 $lockfile = "lock.dat"; # ロックファイル  # 存在すればカウント不可 #=== 設定終了(ここまで)========================================= # ホスト名を取得 &get_host; # カウント &counter; exit; ################################################################## #******************** SUBROUTINE ******************************# ################################################################## #=== カウント ================================================== sub counter { ### ファイルロック(同時アクセスによるデータ破壊を防止)###### if ( $lockkey == 1 ) { $lockflag = &lock; if ( $lockflag == 0 ){ push(@err,'BUSY'); &error; } } ### カウント処理 ############################################# if(!open (IN,"$count_data")){ push(@err,'count_data read error'); &error; } $line = ; close (IN); # 後ろの1文字(\n)を削除 $line =~ s/\n$//; # つなぎ文字(|||)で$lineを分離 ($count,$remote,$time1) = split(/\|\|\|/, $line); # 現在時刻を取得 $time2 = time; # 前回訪問時刻との差を計算 $deftime = $time2 - $time1; # 現在の訪問者と前の訪問者が異なるか、あるいは # $zikan分経過のときはカウントする if ( $remote ne $rehost || $deftime > $zikan*60 ) { $count++; $line = "$count|||$rehost|||$time2"; if (!open (OUT,">$count_data")){ push(@err,'count_data write error'); &error; } print OUT "$line\n"; close (OUT); } ### ロックファイルの削除 ##################################### if ( $lockkey == 1 ) { if (-e $lockfile){ unlink($lockfile); } } ### 表示桁数をフォーマット(00234のように)し$counterに代入 #### $counter = sprintf("%05d",$count); ### SSIの記述部分にカウンタを表示 ############################ &ssi; } #=== ロックファイル ============================================ sub lock { local($flag) = 0; foreach(1..10){ unless(-e $lockfile){ open(LOCK,">$lockfile"); close(LOCK); $flag = 1; last; } sleep(1); } $flag; } #=== ホスト名を取得 ============================================ sub get_host { $rehost = $ENV{'REMOTE_HOST'}; $readdr = $ENV{'REMOTE_ADDR'}; if ($rehost eq "" || $rehost eq "$readdr") { ($p1,$p2,$p3,$p4) = split(/\./,$readdr); $pack = pack("C4",$p1,$p2,$p3,$p4); $rehost = gethostbyaddr("$pack", 2); if ($rehost eq "") { $rehost = $readdr; } } } #=== SSI表示サブルーチン ==================================== sub ssi { print "Content-type: text/html\n\n"; print "\n"; print "\n"; print "$counter\n"; print "\n"; } #=== エラー表示サブルーチン ==================================== sub error { print "Content-type: text/html\n\n"; print "\n"; print "\n"; print "ERROR
\n"; foreach (@err){ print "$_
\n"; } print "\n"; exit; }