#!/usr/local/bin/perl

##################################################################
# グラフィカルアクセスカウンタ v4.0 for UNIX (c)www.rescue.ne.jp #
##################################################################

# 設置構成
#
# /ホームページディレクトリ/
#            |
#            |-- index.html (このファイルにカウンタを表示するとする) (*)
#            |
#            |          このファイルのカウンタを表示させたい場所に次のSSIコマンドを書く.
#            |          <!--#exec cmd="./count/count.pl"-->
#            |
#            |-- /count/
#            |      |
#            |      |-- count.pl (このスクリプト) <755>
#            |      |
#            |      |-- /locktmp/ <777> (作業フォルダ)
#            |              |
#            |              |-- count.dat (カウント開始数が入ったファイル)
#            |
#            |-- /images/
#                    |
#                    |-- 0.gif (数字画像 0)
#                    |-- 1.gif (数字画像 1)
#                    |-- 略
#                    |-- 9.gif (数字画像 9)

# 注意　常に Error(1) が出る場合は、設置不可能な環境にある場合が考えられます.


#■作業フォルダの場所を、ＳＳＩを実行する(*)印のファイルから見た位置で設定する(パス)
$tmp_dir = './count/locktmp/';

#■カウント開始数が入ったファイル名
$file = 'count.dat';

#■画像ディレクトリの位置を設定(ＵＲＬ)
$graphics = 'http://      ?  ?      /images/';

#■カウント数表示を文字にするか画像にするか？
$sw = 1; #  画像:1 文字:0 (文字にする場合は、画像を用意したり画像ディレクトリの位置の設定は必要ない)

#-------------------------------------------------------------------------------------

&lock1;

open(READ,"$tmp_dir$file") || &error("Read Error");
$count = <READ>;
close(READ);

$count++;

$lock = "$$\.lock";

open(WRITE,"> $tmp_dir$lock") || &error("Write Error");
print WRITE $count;
close(WRITE);

&lock2;

if ($sw) {

	foreach (0..length("$count")-1) { $img = substr($count,$_,1);
	print "<img src=\"$graphics$img.gif\" alt=\"$img\" border=\"0\">"; }
}
else { print $count; }

exit;


sub lock1 {

	local($list,@lists);
	local($retry) = 3;

	$list = `ls $tmp_dir$ls` || &error("Error(1)");
	@lists = grep(/\.lock/,split(/\s+/,$list));

	while (@lists) {

		if (--$retry <= 0) {

			foreach (@lists) { unlink "$tmp_dir$_" || &error("Error(2)"); }
			&error("Busy(1)");
		}

		sleep(1);

		$list = `ls $tmp_dir$ls` || &error("Error(3)");
		@lists = grep(/\.lock/,split(/\s+/,$list));
	}
}

sub lock2 {

	local($list,@lists);

	$list = `ls $tmp_dir$ls` || &error("Error(4)");
	@lists = grep(!/$lock/,grep(/\.lock/,split(/\s+/,$list)));

	if (@lists) {

		if (-e "$tmp_dir$lock") { unlink("$tmp_dir$lock"); }
		&error("Busy(2)");
	}

	rename("$tmp_dir$lock","$tmp_dir$file") || &error("Busy(3)");
}

sub error {

	if (-e "$tmp_dir$lock") { unlink("$tmp_dir$lock"); }

	print $_[0];
	exit;
}
