#!C:\Perl\bin\perl -w

#┌─────────────────────────────────
#│  Lime Counter v1.51 (2001/05/13)
#│  Copyright(C) Kent Web 2001
#│  webmaster@kent-web.com
#│  http://www.kent-web.com/
#└─────────────────────────────────
$ver = 'LIME COUNTER v1.51';
#┌─────────────────────────────────
#│ [注意事項]
#│ 1. このスクリプトはフリーソフトです。このスクリプトを使用した
#│    いかなる損害に対して作者は一切の責任を負いません。
#│ 2. 設置に関する質問はサポート掲示板にお願いいたします。
#│    直接メールによる質問は一切お受けいたしておりません。
#└─────────────────────────────────
#
# [ 1. ページカウンタの使い方 ] : 1-2.の使い方を推奨
#
#  1-1. タグの記述例 (1) ページのURLは自動で取得する場合
#    <IMG SRC="htp://〜〜/lime.cgi?page=1&name=PAGENAME">
#
#  1-2. タグの記述例 (2) ページのURLを手動で指定する場合
#    <IMG SRC="cgi-bin/lime.cgi?page=1&name=PAGENAME
#     &hp=http://www.xxx.xxx/~user/">
#     (注：タグは実際には改行しないで下さい）
#
#  注：・1-2. のタグ記述例は見やすくするためにわざと２行にして書いて
#        いますが、実際には改行せずに「１行で」記述してください。
#      ・「PAGENAME」の部分は半角英数字（日本語不可）で記述。
#      ・ page=1 の 1 の数値はページ毎に必ず変えてください。
#
#  1-3. アクセス一覧集計の閲覧例
#     http://www.xxx.xxx/~user/cgi-bin/limemgr.cgi
#
#---------------------------------------------------------------------
#
# [ 2. ダウンロードカウンタの使い方 ] : 2-2.の使い方を推奨
#
#  2-1. タグの記述例 (1) ページのURLは自動で取得する場合
#     <a href="cgi-bin/lime.cgi?down=http://www.xxx.xxx/data.lzh&name=FILENAME">
#      DATA.LZH</a>
#
#  2-2. タグの記述例 (2) ページのURLを手動で指定する場合
#     <a href="cgi-bin/lime.cgi?down=http://www.xxx.xxx/data.lzh&name=FILENAME
#      &hp=http://www.xxx.xxx/~user/">DATA.LZH</a>
#      (注：タグは実際には改行しないで下さい）
#
#  注：・タグ記述例は見やすくするためにわざと２行に書いていますが、
#        実際に記述する場合には改行せずに「１行で」記述してください。
#      ・「FILENAME」の部分は半角英数字（日本語不可）で記述。
#
#  2-3. アクセス一覧集計の閲覧例
#     http://www.xxx.xxx/~user/cgi-bin/limemgr.cgi
#
#---------------------------------------------------------------------
#
# [ 3. チェックモードの使い方 ]
#
#  3-1. http://www.xxx.xxx/~user/cgi-bin/lime.cgi?mode=check
#       mode=checkという引数を付けてブラウザから指定する
#
#---------------------------------------------------------------------
#
# [ 4. 設置例 ]
#
#  public_html / index.html
#       |
#       |
#       +-- cgi-bin / lime.cgi    [755]
#              |      lime.log    [666]
#              |      limemgr.cgi [755]
#              |      jcode.pl    [644]
#              |
#              +-- lock [777] /
#
#---------------------------------------------------------------------


#============#
#  設定項目  #
#============#

# ログファイル名
$logfile = "./lime.log";

# ファイルロック機構
#   0 : しない
#   1 : する (symlink関数式)
#   2 : する (mkdir関数式)
$lockkey = 0;

# ロックファイル
$lockfile = "./lock/lime.lock";

# IPチェックによる重複カウント防止 (0=no 1=yes)
$ip_chk = 0;

# ダウンロード形式（ダウンロードカウンタとして使用する場合のみ）
#   → Locaion関数の使えないサーバは「2」とする
#   1 : Location関数
#   2 : METAタグ
$get_file = 1;

# METAタグジャンプの待ち秒数（ダウンロードカウンタとして使用する場合のみ）
#   → 上記設定で「2」とした場合のみ
$wait = 1;

#============#
#  設定完了  #
#============#

$buffer = $ENV{'QUERY_STRING'};
@pairs = split(/&/, $buffer);
foreach (@pairs) {
	($name, $value) = split(/=/);
	$value =~ tr/+/ /;
	$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

	$value =~ s/\"/&quot;/g;
	$value =~ s/</&gt;/g;
	$value =~ s/>/&lt;/g;

	$in{$name} = $value;
}
$page = $in{'page'};
$name = $in{'name'};
$mode = $in{'mode'};
$hp   = $in{'hp'};
$down = $in{'down'};
$down =~ s/^http\:\/\/?//;

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

# URLの引数がない場合はリンク元情報を取得する
if ($hp eq "") {
	$hp = $ENV{'HTTP_REFERER'};
	$hp =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	$hp =~ s/<([^>]|\n)*>//g;
}
$hp =~ s/^http\:\/\/?//;
if ($hp eq "") { $hp = "unknown"; }

# IPアドレスを取得
$addr = $ENV{'REMOTE_ADDR'};

# ロック開始
&lock if ($lockkey);

# ログを開く
if ($down) { $page = $down; }

open(IN,"$logfile") || &error("$logfile","LK");
@lines = <IN>;
close(IN);

# マッチング／カウントアップ処理
$flag=0;
@new=();
#ホストが127.0.0.1なら何もしない
if ($addr =~ /127\.0\.0\.1/) { $flag=2; }
else {
foreach $line (@lines) {
	($no,$hpg,$count,$title,$ip) = split(/<>/, $line);

	if ($page eq "$no") {
		# IPアドレスが同じ場合はカウントアップしない
		if ($ip_chk && $addr eq "$ip") { $flag=2; last; }

		# $hpg, $title がない場合
		if ($hpg eq "") { $hpg = $hp; }
		if ($title eq "") {
			$title = $name;
		}

		$flag=1;
		$count++;
		$line = "$no<>$hpg<>$count<>$title<>$addr<>\n";
	}
	push(@new,$line);
}
}

# 既存ログ更新
if ($flag == 1) {
	open(OUT,">$logfile") || &error("$logfile","LK");
	print OUT @new;
	close(OUT);
}
# 新規ページ追加更新
elsif ($flag == 0 && $hp ne "") {
	open(OUT,">>$logfile") || &error("$logfile","LK");
	print OUT "$page<>$hp<>1<>$name<>$addr<>\n";
	close(OUT);
}

# ロック解除
&unlock if ($lockkey);

# ダウンロードカウンタの場合
if ($down) {

	# METAタグ方式
	if ($get_file == 2) {
		print "Content-type: text/html\n\n";
		print "<html><head>\n";
		print "<META HTTP-EQUIV=\"refresh\" CONTENT=\"$wait\; URL=http://$down\">\n";
		print "</head>\n";
		print "<body>\n";
		print "<center><h4>- しばらくお待ちください -</h4>\n";
		print "<P>しばらく待ってもダウンロードできない場合は <a href=\"http://$down\">ここ</a> をクリックしてください\n";
		print "<FORM><INPUT TYPE=button VALUE=\"もどる\" onClick=\"history.back()\"></FORM><br><br>\n";
		print "</body>\n</html>\n";
		exit;
	}

	# IISサーバ(PerlIS)対応
	if ($ENV{'PERLXS'} eq "PerlIS") {
		print "HTTP/1.0 302 Temporary Redirection\r\n";
		print "Content-type: text/html\n";
	}
	print "Location: http://$down\n\n";

} else {
	# ダミー画像を定義：透明GIF (2x2ピクセル、16色)
	@array = ("47","49","46","38","39","61","02","00","02","00","80","00",
		"00","00","00","00","ff","ff","ff","21","f9","04","01","00","00",
		"01","00","2c","00","00","00","00","02","00","02","00","00","02",
		"02","8c","53","00","3b");

	# ダミー画像を表示
	print "Content-type: image/gif\n\n";
	foreach (@array) {
		$data = pack('C*',hex($_));
		print $data;
	}
}
exit;

#--------------#
#  ロック処理  #
#--------------#
sub lock {
	local($retry)=5;
	# 3分以上古いロックは削除する
	if (-e $lockfile) {
		($mtime) = (stat($lockfile))[9];
		if ($mtime && $mtime < time - 180) { &unlock; }
	}
	# symlink関数式ロック
	if ($lockkey == 1) {
		while (!symlink(".", $lockfile)) {
			if (--$retry <= 0) { &error; }
			sleep(1);
		}
	# mkdir関数式ロック
	} elsif ($lockkey == 2) {
		while (!mkdir($lockfile, 0755)) {
			if (--$retry <= 0) { &error; }
			sleep(1);
		}
	}
}

#--------------#
#  ロック解除  #
#--------------#
sub unlock {
	if ($lockkey == 1) { unlink($lockfile); }
	elsif ($lockkey == 2) { rmdir($lockfile); }
}

#--------------#
#  エラー処理  #
#--------------#
sub error {
	&unlock if ($lockkey && $_[1] eq 'LK');
	die "Error : $_[0]";
}

#------------------#
#  チェックモード  #
#------------------#
sub check {
	print "Content-type: text/html\n\n";
	print "<html><head><title>LIME COUNTER</title></head>\n";
	print "<body>\n<h2>Check Mode</h2>\n<UL>\n";

	# ログファイルのパス確認
	if (-e $logfile) {
		print "<LI>ログファイルのパス : OK\n";
	} else {
		print "<LI>ログファイルのパス : NG → $logfile\n";
	}

	# ログファイルのパーミッション（読みこみ）
	if (-r $logfile && -w $logfile) {
		print "<LI>ログファイルのパーミッション : OK\n";
	} else {
		print "<LI>ログファイルのパス : NG → $logfile\n";
	}

	# ロックディレクトリ
	print "<LI>ロック形式：";
	if ($lockkey == 0) { print "ロック設定なし\n"; }
	else {
		if ($lockkey == 1) { print "symlink\n"; }
		else { print "mkdir\n"; }
		$lockfile =~ s/(.*)[\\\/].*$/$lockdir = $1/e;
		print "<LI>ロックディレクトリ：$lockdir\n";

		if (-d $lockdir) { print "<LI>ロックディレクトリのパス：OK\n"; }
		else { print "<LI>ロックディレクトリのパス：NG → $lockdir\n"; }

		if (-r $lockdir && -w $lockdir && -x $lockdir) {
			print "<LI>ロックディレクトリのパーミッション：OK\n";
		} else {
			print "<LI>ロックディレクトリのパーミッション：NG → $lockdir\n";
		}
	}

	# 著作権表示：削除改変を禁止します
	print "</UL>\n<P><small><!-- $ver -->\n";
	print "Copyright(C) <a href='http://www.kent-web.com/'>Kent Web</a> 2001\n";
	print "</small>\n</body>\n</html>\n";
	exit;
}
