#!/usr/bin/perl
#
#	↑サーバーのperlまでのパス
#		動かなかったら #!/usr/local/bin/perlに変更してみたください

###############################################
#                                             #
#   CGI's  GifCounter2                        #
#   E-Mail:info@cgis.biz                      #
#   HomePage:http://www.cgis.biz/             #
#   (C) CGI's 2003/7/19                       #
#                                             #
###############################################

#####　説　明　###############################################
#
#・ファイル構成とパーミッション
#gif_counter/             (755)
#├cnt.cgi                (755)
#├cnt.dat                (666)
#├chk.dat                (666)
#├lib/                   (755)
#│　└gifcat.pl          (644)
#│
#└img/                   (755)
#　　└0〜9.gif           (644)
#・カウンターを表示したいHTMLの任意の場所に以下のタグを記述してください。
#  <a href="http://www.cgis.biz/"><img src="./cnt.cgi?mode=total" border="0"></a>
#  <a href="http://www.cgis.biz/"><img src="./cnt.cgi?mode=today" border="0"></a>
#  <a href="http://www.cgis.biz/"><img src="./cnt.cgi?mode=last" border="0"></a>
#  ※mode=totalが合計、todayが今日、lastが昨日のカウントを表示します。
#  ※記述する順番・数はどうでもいいです。ただし、cnt.cgi(本ファイル)の設定項目、
#   「■最初のimgタグのmode設定($f_mode)」に最初に記述したタグのmodeを設定してください。
#
#     例）上記のタグの順番なら下記のようになります。
#　　　　　$f_mode="total";
#
#・cnt.cgiの設定部分で各ファイルまでのパスを設定。
#  他の設定は前段を除いてお好みにしてください。
#・libフォルダはcnt.cgiと同じフォルダに入れてください。
#・動かなかったらperlまでのパスを変更
#　/usr/local/bin/perl
#・それでも動かなかったらあきらめる
#・バグあったらおしえてください。
#
############################################################

########################　設 定　########################################

#■カウントデータファイルとパス設定
$cnt_dat="./cnt.dat";
#■アクセスログ（アドレス・時間）データファイルとパス設定
$chk_dat="./chk.dat";
#■カウンターgif画像フォルダまでのパス設定
$gif_fol="./img/";
#■最初のimgタグのmode設定
$f_mode="total";
#■重複カウントを許さない場合
#chk.dat内Logの中に同じアドレスがあり、
#かつ、同アドレスのカウントアップを一定時間しない場合
#「1」
#■重複カウントを許す場合
#「0」
$check_cnt=1;
#■以下は重複カウントを許さない場合関係してくる設定
#■チェックする一定の時間（秒数）
$check_time=60*60*1;
#■チェックするのに残すLogの数
$log=50;
#####################################################################

require './lib/gifcat.pl';
require './lib/cgi-lib.pl';

&ReadParse(*in);
$mode=$in{'mode'};
unless($mode eq "total" || $mode eq "today" || $mode eq "last"){
	$mode="";
}

#今日、昨日のカウントを振り分けるため、今日と昨日の日付を取得
($n_sec,$n_min,$n_hour,$n_mday,$n_mon,$n_year,$n_wday,$n_yday,$n_isdst)=localtime(time);
$now_day=($n_year+1900).(sprintf("%02d",($n_mon+1))).(sprintf("%02d",($n_mday)));

($l_sec,$l_min,$l_hour,$l_mday,$l_mon,$l_year,$l_wday,$l_yday,$l_isdst)=localtime(time-(60*60*24));
$last_day=($l_year+1900).(sprintf("%02d",($l_mon+1))).(sprintf("%02d",($l_mday)));

$now_time=time;
$addr = $ENV{'REMOTE_ADDR'};

if($mode eq "$f_mode"){
	open (CHK,"+<$chk_dat");
	flock(CHK,2);
	@array=<CHK>;
	$flg=1;
	if($check_cnt==1){
		#今回アクセスしたアドレスがLogの中にあり、かつ、一定時間経過してなければフラグを「0」（カウントしない）
		foreach $line (@array){
			($kako_time,$kako_addr)=split(/<>/,$line);
			chomp $kako_addr;
			if($kako_addr eq $addr && ($kako_time + $check_time) > $now_time){
				$flg=0;
				last;
			}
		}
	}
	#重複するIPアドレスは削除
	foreach $line (@array){
		($kako_time,$kako_addr)=split(/<>/,$line);
		chomp $kako_addr;
		if($kako_addr ne $addr){
			$temp=join("<>",$kako_time,$kako_addr);
			push (@new_array,"$temp\n");
		}
	}
	#今回のアクセス時間とアドレスを纏める
	$konkai=join("<>",($now_time,$addr));
	push (@new_array,"$konkai\n");
	while(@new_array > $log){
		shift @new_array;
	}
	truncate(CHK,0);
	seek(CHK,0,0);
	print CHK @new_array;
	close CHK;

	#ログ読み込み
	open(CNT,"+<$cnt_dat");
	flock(CNT,2);
	@cntarrey=<CNT>;

	foreach $line (@cntarrey){
		chomp $line;
		($cntid,$cntday,$cnt)=split(/<>/,$line);
		if($cntid eq "total"){
			$totalid=$cntid;
			$totalday=$cntday;
			$totalcnt=$cnt;
		}
		elsif($cntid eq "today"){
			if($cntday==0){
				$cntday=$now_day;
			}
			$todayid=$cntid;
			$todayday=$cntday;
			$todaycnt=$cnt;
		}
		elsif($cntid eq "lastday"){
			if($cntday==0){
				$cntday=$last_day;
			}
			$lastid=$cntid;
			$lastday=$cntday;
			$lastcnt=$cnt;
		}
	}

	if($now_day == $todayday){
		if($flg == 1){
			$todaycnt++;
		}
	}
	elsif($last_day == $todayday){
		$lastcnt=$todaycnt;
		if($flg == 1){
			$todaycnt=1;
		}
		else{
			$todaycnt=0;
		}
		$lastday=$last_day;
		$todayday=$now_day;
	}
	elsif($last_day > $todayday) {
		$lastcnt=0;
		if($flg == 1){
			$todaycnt=1;
		}
		else{
			$todaycnt=0;
		}
		$lastday=$last_day;
		$todayday=$now_day;
	}
	if($flg == 1){
		$totalcnt++;
	}
	truncate(CNT,0);
	seek(CNT,0,0);
	print CNT ("$totalid<>$totalday<>$totalcnt\n");
	print CNT ("$todayid<>$todayday<>$todaycnt\n");
	print CNT ("$lastid<>$lastday<>$lastcnt\n");
	close(CNT);
}

open(CNT,"$cnt_dat");
flock(CNT,2);
@cntarrey2=<CNT>;

foreach $line2 (@cntarrey2){
	chomp $line2;
	($cntid,$cntday,$cnt)=split(/<>/,$line2);
	if($cntid eq "total"){
		$totalid=$cntid;
		$totalday=$cntday;
		$totalcnt=$cnt;
	}
	elsif($cntid eq "today"){
		$todayid=$cntid;
		$todayday=$cntday;
		$todaycnt=$cnt;
	}
	elsif($cntid eq "lastday"){
		$lastid=$cntid;
		$lastday=$cntday;
		$lastcnt=$cnt;
	}
}

$totalcnt=sprintf("%05d",$totalcnt);
$todaycnt=sprintf("%05d",$todaycnt);
$lastcnt=sprintf("%05d",$lastcnt);

if($mode eq "total"){
	for($i=0;$i<length($totalcnt);$i++){
		$n=substr($totalcnt,$i,1);
		push(@total,"$gif_fol$n.gif");
	}
	print "Content-type:image/gif\n\n";
	binmode(STDOUT);
	print &gifcat'gifcat(@total);
}

if($mode eq "today"){
	for($i=0;$i<length($todaycnt);$i++){
		$n=substr($todaycnt,$i,1);
		push(@today,"$gif_fol$n.gif");
	}
	print "Content-type:image/gif\n\n";
	binmode(STDOUT);
	print &gifcat'gifcat(@today);
}

if($mode eq "last"){
	for($i=0;$i<length($lastcnt);$i++){
		$n=substr($lastcnt,$i,1);
		push(@last,"$gif_fol$n.gif");
	}
	print "Content-type:image/gif\n\n";
	binmode(STDOUT);
	print &gifcat'gifcat(@last);
}

close (CNT);

exit;

