#!/usr/bin/perl

#↑このパスはプロバイダに応じて変更してください

# 最新バージョンは次のところに置いてます。
# http://homepage2.nifty.com/sophia0/sub04.html
# $ver = 'txtcount.cgi v0.8a by techan';

# 同一IPアドレスの場合にカウントしない時間間隔(秒)
$interval = 600;

# ログ・集計用ファイルを置くフォルダ(最後は/で閉じること)
$logdir = './';

# カウントログのファイル名(特に変更の必要なし)
$loga = 'count.txt';
$logb = 'count.bak';

# 数字を３桁ずつコンマで区切るか(区切る:1  区切らない:0)
$comma_use = 1;

# 集計を行うか(行う:1  行わない:0) オプション
$calcuse = 1;

# 集計用ファイルの名前(集計する場合のみ) オプション
$dayfile = 'day.txt';		# 今月の日計
$dayback = 'dab.txt';		# 先月の日計
$monfile = 'mon.txt';		# 月計

# 世界時からの時差設定(秒)(特に変更の必要なし)
$ajst = 9*60*60;

&main_routine;	# この行は消さないで

# JavaScript部分
# ここで色、文字、タグ等を直接修正してください
print <<"_EOM_";
document.write('<!-- access_count -->');
//End-->
_EOM_
# 設定ここまで(ここから先は腕に自信のある方のみ弄ってください)

exit;

# -------------
# Main Routine
# -------------
sub main_routine
{
$loga = $logdir.$loga;
$logb = $logdir.$logb;
$new_id = "$ENV{'REMOTE_ADDR'}\/$ENV{'HTTP_X_FORWARDED_FOR'}\/$ENV{'HTTP_USER_AGENT'}";
$seconds = time;
$mday = (gmtime($seconds + $ajst))[3];
$oka=0;
$okb=0;
@linea = ();
@lineb = ();

# Read Log
if (-f $loga) {
	open(LOGA,"< $loga") || &error("$loga を読めません");
	$linea = <LOGA>;
	close(LOGA);
	@linea = split(/\|/, $linea);
	$oka = 1 if ($linea[6] eq 'EOF');
}
## ファイルのパーミッションが666でないと書きこみができないときは
## 以下の５行の行頭の # を取り外してください
 else {
	open(LOGA,"> $loga") || &error("$loga を作れません");
	close(LOGA);
	chmod(0666, $loga);
 }

if (-f $logb) {
	open(LOGB,"< $logb") || &error("$logb を読めません");
	$lineb = <LOGB>;
	close(LOGB);
	@lineb = split(/\|/, $lineb);
	$okb = 1 if ($lineb[6] eq 'EOF');
}
## ファイルのパーミッションが666でないと書きこみができないときは
## 以下の５行の行頭の # を取り外してください
 else {
	open(LOGB,"> $logb") || &error("$logb を作れません");
	close(LOGB);
	chmod(0666, $logb);
 }

$write = ($linea[0] > $lineb[0]) ? 'b' : 'a';
$write = 'b' if (!$okb);
$write = 'a' if (!$oka);
if ($write eq 'b') {
	($total_cnt,$today_cnt,$yester_cnt,$old_date,$old_tm,$old_id) = @linea;
	$log = $logb;
} else {
	($total_cnt,$today_cnt,$yester_cnt,$old_date,$old_tm,$old_id) = @lineb;
	$log = $loga;
}

# Write Log
if (($seconds - $old_tm) > $interval || $new_id ne $old_id) {
	$total_cnt++;
	if ($mday == $old_date) { $c_flag = 0; $today_cnt++; }
	else { $c_flag = 1; $yester_cnt = $today_cnt; $today_cnt = 1; }
	&day_calc if ($calcuse && $c_flag);
	$line = "$total_cnt\|$today_cnt\|$yester_cnt\|$mday\|$seconds\|$new_id\|EOF\|";
	open(TMP,"+< $log") || open(TMP,"> $log") || &error("$log に書きこめません");
	eval 'flock(TMP, 2);';
	truncate(TMP, 0);
	seek(TMP, 0, 0);
	print TMP $line;
	close(TMP);
}

if ($comma_use) {
	$total_cnt = &fig_place($total_cnt);
	$today_cnt = &fig_place($today_cnt);
	$yester_cnt = &fig_place($yester_cnt);
}
$yester_cnt = 0 if (!$yester_cnt);
&txt_header;
}

# Mark by a comma each three figures
sub fig_place
{
local($_) = $_[0];

## perl4
# 1 while s/(.*\d)(\d\d\d)/$1,$2/g;

## perl5
1 while s/(\d)(\d\d\d)(?!\d)/$1,$2/g;

return($_);
}

# Error Output
sub error
{
&txt_header;
print "document.write(\"$_[0]<br>\"); \n";
print "//End-->\n";
exit;
}

# Text Header
sub txt_header
{
$|=1;
print "Content-type: text/plain\n\n";
print "<!--\n";
}

sub day_calc
{
$dayfile = $logdir.$dayfile;
$dayback = $logdir.$dayback;
$monfile = $logdir.$monfile;
if ($old_tm) {
	if (-f $dayfile) {
		open(DAY,"< $dayfile");
		@lines = <DAY>;
		close(DAY);
		if ($#lines >=0) { ($c_cnt,$c_tm) = split(/\|/, $lines[$#lines]); }
	} else {
		@lines = ();

## ファイルのパーミッションが666でないと書きこみができないときは
## 以下の３行の行頭の # を取り外してください
		open(DAX,"> $dayfile") || &error("$dayfile を作れません");
		close(DAX);
		chmod(0666, $dayfile);

	}
	unless ($c_cnt == $yester_cnt && $c_tm == $old_tm) {
		$appe = "$yester_cnt\|$old_tm\|\n";
		push(@lines, $appe);
		open(DAW,">> $dayfile") || &error("$dayfile に追記できません");	
		eval 'flock(DAW, 2);';
		print DAW $appe;
		close(DAW);
		if ($mday < $old_date) {
			rename($dayfile, $dayback) || &error("$dayfile をリネームできません");
			$mon_cnt = 0;
			for ($i=0;$i<=$#lines;$i++) {
				$add_cnt = (split(/\|/, $lines[$i]))[0];
				$mon_cnt += $add_cnt;
			}
			open(MON,">> $monfile") || &error("$monfile に追記できません");
			eval 'flock(MON, 2);';
			print MON "$mon_cnt\|$old_tm\|\n";
			close(MON);
		}
	}
}
}
__END__
