#!/usr/bin/perl
#  
# パラメータの省略値
#
#  最低表示桁
$digit_fix = 6;
#  画像の有るディレクトリ
$digit_dir = 'img';
#  何進で表示するか
$digit_base = 10;

require './gifcat.pl';

$basedir = ".";

&main;

sub main{
	&check_input;
	&lock;
	&inc_counter;
	&unlock;
	&show_counter;
}

sub check_input{

	$buffer = $ENV{'QUERY_STRING'};
	@prm = split("&", $buffer);
	
	$cname = ($prm[0] =~ /^\w+$/) ? $prm[0] : 'cnt';
	$incr  = ($prm[1] == 1)       ? 1       : 1;
	$keta  = ($prm[2] =~ /^\d+$/) ? $prm[2] : $digit_fix;
	$type  = ($prm[3] =~ /^\w+$/) ? $prm[3] : $digit_dir;
	$dsb   = ($prm[4] =~ /^\w+$/) ? $prm[4] : $digit_base;

	# カウンタ名が指定されてない
	($cname) || &error(0,"no count file");
	# 画像ファイルがない
	unless(-f "$basedir/$type/0.gif"){
		&error(0, "$basedir/$type/0.gif not found");
	}
	$lockfile="$basedir/$cname.lock";
}

sub inc_counter{
	$cnt = &openfile("$basedir/$cname.txt");

	if ($incr == 1) {
		$cnt++;
		&updatefile("$basedir/$cname.txt", $cnt);
	}
}

sub show_counter{

	while ($cnt > 0){
		$ds = $cnt % $dsb;
		unshift(@nos, "$ds");
		$cnt /= $dsb;
		$cnt = int($cnt);
	}

	while(@nos < $keta){ unshift(@nos, "0"); }

	for(0..$#nos){ $nos[$_]="$basedir/$type/$nos[$_].gif"; }

	print "Content-type: image/gif\n\n";
	binmode(STDOUT);
	$| = 1;
	print &gifcat'gifcat(@nos);
}

sub openfile{
	local($cfile) = @_;
	local($cnt);
	open(FILE, "$cfile") || die &error(1, $cfile);
	$cnt = <FILE>;
	close(FILE);
	$cnt;
}

sub updatefile{
	local($cfile, $cnt) = @_;
	open(FILE, ">$cfile") || die &error(2, $cfile);
	print FILE $cnt;
	close(FILE);
}

sub lock{
	local($try) = 3;
	while(-f $lockfile){
		if(--$try <= 0){
			 &error(3);
		}
		sleep(1);
	}
	open(FILE,">$lockfile") || die &error(2);
	close(FILE);
}

sub unlock{
	unlink($lockfile);
}

sub error{
	local($id, $fname)=@_;

	$msg[0] = "引数に間違いがあります";
	$msg[1] = "ファイルが開けません";
	$msg[2] = "ファイルに書きこめません";
	$msg[3] = "ロック中です";

	print "Content-type: text/plain\n\n";
	print "<< NCOUNT Error Message >>\n";
	print "$msg[$id] ($fname)";

	if ($id == 0){ exit; }

	# 約15秒以内のロック？
	if ($id == 3) {
		@sts = lstat($lockfile);
		$tn = time();
		if ($tn - $sts[9] < 15){ exit; }
	}

	&unlock;
	exit;
}
