#!/usr/bin/perl

#┌─────────────────────────────────
#│  Lime Counter v1.71 (2002/10/03)
#│  Copyright(C) Kent Web 2002
#│  webmaster@kent-web.com
#│  http://www.kent-web.com/
#└─────────────────────────────────
$ver = 'LIME COUNTER v1.71';
#┌─────────────────────────────────
#│ [注意事項]
#│ 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 = 1;

# ロックファイル
$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;

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

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

	$val =~ s/&/&amp;/g;
	$val =~ s/"/&quot;/g;
	$val =~ s/</&gt;/g;
	$val =~ s/>/&lt;/g;
	$val =~ s/\0//g;

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

# チェックモード
if (!$buf || $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");
@lines = <IN>;
close(IN);

# マッチング／カウントアップ処理
$flag=0;
@new=();
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");
	print OUT @new;
	close(OUT);
}
# 新規ページ追加更新
elsif ($flag == 0 && $hp ne "") {
	open(OUT,">>$logfile") || &error("$logfile");
	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<body>\n";
		print "<center><h4>- しばらくお待ちください -</h4>\n";
		print "しばらく待ってもダウンロードできない場合は
			<a href=\"http://$down\">ここ</a> をクリックしてください\n";
		print "<form><input type=button value='前画面にもどる' onClick=\"history.back()\"></form>\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
	@err = ("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 (@err) {
		$data = pack('C*',hex($_));
		print $data;
	}
}
exit;

#--------------#
#  ロック処理  #
#--------------#
sub lock {
	local($retry)=5;
	# 1分以上古いロックは削除する
	if (-e $lockfile) {
		local($mtime) = (stat($lockfile))[9];
		if ($mtime < time - 60) { &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);
		}
	}
	$lockflag=1;
}

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

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

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

	# ログファイルのパス確認
	if (-e $logfile) {
		print "<LI>ログファイルのパス : OK\n";
		# ログファイルのパーミッション
		if (-r $logfile && -w $logfile) {
			print "<LI>ログファイルのパーミッション : OK\n";
		} else {
			print "<LI>ログファイルのパーミッション : NG → $logfile\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"; }
		($lockdir) = $lockfile =~ /(.*)[\\\/].*$/;
		print "<LI>ロックディレクトリ：$lockdir\n";

		if (-d $lockdir) {
			print "<LI>ロックディレクトリのパス：OK\n";
			if (-r $lockdir && -w $lockdir && -x $lockdir) {
				print "<LI>ロックディレクトリのパーミッション：OK\n";
			} else {
				print "<LI>ロックディレクトリのパーミッション：NG → $lockdir\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> 2002\n";
	print "</small>\n</body>\n</html>\n";
	exit;
}

__END__

