#!/usr/local/bin/perl
#
# このlinkc.cgi.txtはlinkc.cgiに名前を変更してからご利用ください。

# リンクカウンタ v2.00 is Free(フリーソフト).
# by www.rescue.ne.jp <CGI RESCUE>
#
# [History]
# 02/Oct/98 v1.00 初期リリース
# 02/Oct/98 v1.10 QUERY_STRING仕様に変更
# 07/Nov/06 v2.00 データファイルに .txt を付加した仕様に変更 (v1.xとの互換性なし)

# ○リンクの仕方
#
# <a href="http://www.rescue.ne.jp/">ネットサーフレスキュー[Web裏技]</a>
#   ↓
# <a href="linkc.cgi?url=http://www.rescue.ne.jp/&file=urawaza">ネットサーフレスキュー[Web裏技]</a>
#
# ・linkc.cgiにアクセスするように設定します。url=にはリンク先を、file=にはリンク数を記録しておくファイル名(半角英数字)を設定し、
# それらを & でつなぎます。設定内に " を使うことは出来ません。
#
# ・リンク数は、/linkc/linkdata/ フォルダ内にある、それぞれのリンク数を記録しておくファイル名をダウンロードして見るか、
# Web上で表示したい場合は SSI を利用します。このとき、拡張子 .txt を付加してください。
#
# <a href="linkc.cgi?url=http://www.rescue.ne.jp/&file=urawaza">ネットサーフレスキュー[Web裏技]</a> (<!--#exec cmd="cat ./linkdata/urawaza.txt"-->)
#
# ・SSIが使えないサーバの場合は、
#
# <!--#include virtual="./linkc/linkdata/urawaza.txt"--> を
# <a href="./linkc/linkdata/urawaza.txt">カウント数を見る</a> に変えてください。

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

#■データディレクトリのパスを設定 最後は/で閉じること
$basedir = './linkdata/';

#■エラー用画面のBODY設定
$body = '<body>';

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

$buffer = $ENV{'QUERY_STRING'};

@pairs = split(/&/,$buffer);
foreach $pair (@pairs) {

	($name,$value) = split(/=/,$pair);
	$value =~ tr/+/ /;
	$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
	$in{$name} = $value;
}

#入力チェック

$LOCATION = $in{'url'};
if ($LOCATION =~ /(https?|ftp|gopher|telnet|whois|news)\:/) { ; } else { &error('設定エラー',"アクセスするファイルのURLが正しく設定されていません.<br>確認→ $LOCATION"); }

$FILE = $in{'file'};
if ($FILE =~ /\W|^$/) { &error('設定エラー',"カウントファイル名が正しく設定されていません.<br>半角英数字(_を含む)のみ設定できます.<br>確認→ $FILE"); }

#処理ファイル設定

$file = $basedir . $FILE;

if (!-e "$file.txt") {

	if (!open(NEW,"> $file.txt")) { &error('動作不良',"ファイル$FILEを新規作成できません."); }

	#初期値1を記録する
	print NEW "1";
	close NEW;

	#FTPで編集可能にしておく
	chmod(0666,"$file.txt");
}
elsif (open(F, "+< $file.txt")) {

	flock F, 2;

	$c = <F>;
	$c =~ s/\n//g;
	$c ++;

	eval 'truncate F,0;'; # truncate()が使えないサーバでは致命的なエラーとなる
	seek(F,0,0);

	print F $c;

	close(F);
}
else { &error('その他のエラー',$!); }


#ファイルを呼び出す

print "Location: $LOCATION\n\n";
exit;

sub error {

	if (-e $lockfile) { unlink($lockfile); }

	print "Content-type: text/html\n\n";
        print "$body\n";
        print "<h1>$_[0]</h1>\n";
	print "<h3>$_[1]</h3>\n";
        print "</body></html>\n";
        exit;
}