#!/usr/bin/perl

#┌─────────────────────────────────
#│ DAY COUNTER-EX v3
#│ dayx.cgi - 2008/02/04
#│ Copyright (c) KentWeb
#│ webmaster@kent-web.com
#│ http://www.kent-web.com/
#└─────────────────────────────────

# 外部ファイル取り込み
require './init.cgi';
require $gifcat;

# 引数を解釈
$mode = $ENV{'QUERY_STRING'};
$mode =~ s/\W//g;

# 非更新系は1秒待ち
if (($type == 1 && $mode eq "yes") || ($type == 1 && $mode eq "today") || ($type == 0 && $mode eq "yes")) { sleep(1); }

# チェックモード
if (!$mode || $mode eq 'check') { &check; }

# カウンタ処理
&counter;

#------------------------------------------------
#  カウンタ処理
#-------------------------------------------------
sub counter {
	# 記録ファイルから読み込み
	open(DAT,"+< $logfile") || &error;
	eval "flock(DAT, 2);";
	my $data = <DAT>;

	# 記録ファイルを分解
	local($key, $yes, $today, $count, $youbi, $ip) = split(/<>/, $data);

	# 日時を取得
	$ENV{'TZ'} = "JST-9";
	local($mday,$mon,$year,$wday) = (localtime(time))[3..6];
	$year += 1900;
	$mon = sprintf("%02d", $mon+1);
	my @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
	my $thisday = $week[$wday];
	local($date) = "$year/$mon";

	# IPチェック
	my $flg;
	if ($ip_check) {
		$addr = $ENV{'REMOTE_ADDR'};
		if ($addr eq $ip) { $flg = 1; }
	}

	# 本日のカウント数をキーにカウントアップ
	if ((!$flg && $type && $mode eq 'gif') || (!$flg && !$type && $mode eq 'today')) {

		$count++;

		## 当日処理
		if ($key eq $mday) {
			$today++;

			# ログをフォーマット
			$data = "$key<>$yes<>$today<>$count<>$thisday<>$addr<>\n";

		## 翌日処理
		} else {
			# ログをフォーマット
			$data = "$mday<>$today<>1<>$count<>$thisday<>$addr<>\n";

			&day_count;
			&mon_count;
		}

		# ログを更新
		seek(DAT, 0, 0);
		print DAT $data;
		truncate(DAT, tell(DAT));
		close(DAT);
	}

	# カウンタ画像出力
	if ($mode eq "gif") {
		&count_view($count, $digit1, $gifdir1);
	} elsif ($mode eq "yes") {
		&count_view($yes, $digit2, $gifdir2);
	} else {
		&count_view($today, $digit2, $gifdir2);
	}
	exit;
}

#-------------------------------------------------
# カウンタ出力処理
#-------------------------------------------------
sub count_view {
	my ($data, $digit, $dir) = @_;

	# 桁数調整
	while (length($data) < $digit) {
		$data = '0' . $data;
	}

	my @view;
	foreach ( split(//, $data) ) {
		push(@view,"$dir/$_.gif");
	}

	# 画像連結
	print "Content-type: image/gif\n\n";
	binmode(STDOUT);
	print &gifcat::gifcat(@view);
}

#-------------------------------------------------
#  日次カウント
#-------------------------------------------------
sub day_count {
	# ログの日次キーより本日の日が小さければ月が変わったと判断する
	if ($mday < $key) {
		open(DB,"+> $dayfile") || &error;
		eval "flock(DB, 2);";
		close(DB);

	# 月内での処理
	} else {
		if ($key < 10) { $key = "0$key"; }

		open(DB,">> $dayfile") || &error;
		eval "flock(DB, 2);";
		print DB "$mon/$key ($youbi)<>$today<>\n";
		close(DB);
	}
}

#-------------------------------------------------
#  月間カウント
#-------------------------------------------------
sub mon_count {
	my @mons;

	open(MON,"+< $monfile") || &error;
	eval "flock(MON, 2);";

	# 初めてのアクセスの場合
	if (-z $monfile) {

		$mons[0] = "$date<>$today<>\n";

	} else {

		@mons = <MON>;

		# ログ配列の最終行を分解
		$mons[$#mons] =~ s/\n//;
		my ($y_m, $cnt) = split(/<>/, $mons[$#mons]);

		# 当月処理
		if ($y_m eq $date) {
			$cnt += $today;
			$mons[$#mons] = "$y_m<>$cnt<>\n";

		# 翌月処理
		#（ログ配列の最終行が $dateと異なれば、月が変ったと判断する）
		} else {
			$cnt += $today;
			$mons[$#mons] = "$y_m<>$cnt<>\n";
			push(@mons,"$date<>0<>\n");
		}
	}

	# ログファイルを更新
	seek(MON, 0, 0);
	print MON @mons;
	truncate(MON, tell(MON));
	close(MON);
}

#-------------------------------------------------
#  エラー処理
#-------------------------------------------------
sub error {
	my @err = (
		'47','49','46','38','39','61','2d','00','0f','00','80','00',
		'00','00','00','00','ff','ff','ff','2c','00','00','00','00',
		'2d','00','0f','00','00','02','49','8c','8f','a9','cb','ed',
		'0f','a3','9c','34','81','7b','03','ce','7a','23','7c','6c',
		'00','c4','19','5c','76','8e','dd','ca','96','8c','9b','b6',
		'63','89','aa','ee','22','ca','3a','3d','db','6a','03','f3',
		'74','40','ac','55','ee','11','dc','f9','42','bd','22','f0',
		'a7','34','2d','63','4e','9c','87','c7','93','fe','b2','95',
		'ae','f7','0b','0e', '8b','c7','de','02','00','3b',
	);

	print "Content-type: image/gif\n\n";
	foreach (@err) {
		my $data = pack('C*',hex($_));
		print $data;
	}
	exit;
}

#-------------------------------------------------
#  チェックモード
#-------------------------------------------------
sub check {
	print "Content-type: text/html\n\n";
	print <<EOM;
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=shift_jis">
<title>DAY COUNTER-EX</title></head>
<body>
<h2>Check Mode</h2>
<ul>
EOM

	# ログファイル確認
	foreach ( $logfile, $dayfile, $monfile ) {
		# パス
		if (-e $_) {
			print "<li>$_ → パス OK!\n";

			# パーミッション
			if (-r $_ && -w $_) {
				print "<li>$_ → パーミッション OK!\n";
			} else {
				print "<li>$_ → パーミッション NG!\n";
			}
		} else {
			print "<li>$_ → パス NG!\n";
		}
	}

	# 画像ディレクトリ
	foreach ( $gifdir1, $gifdir2 ) {
		if (-d $_) {
			print "<li>$_ → 画像ディレクトリ OK!\n";

			# 画像
			foreach $n (0 .. 9) {
				if (-e "$_/$n.gif") {
					print "<li>$_/$n.gif → OK!\n";
				} else {
					print "<li>$_/$n.gif → NG!\n";
				}
			}
		} else {
			print "<li>$_/$n.gif → 画像ディレクトリ NG!\n";
		}
	}

	# 著作権表示：削除禁止
	print <<EOM;
<li>バージョン : <a href="http://www.kent-web.com/">$ver</a>
</ul>
</body>
</html>
EOM
	exit;
}


