#!/usr/local/bin/perl

require './gifcat.pl';

#----------------------------
$ver="ManyCounter v2.4";
# (複数GIFカウンタ)
#----------------------------
# Copyright(C) りゅういち
# E-MAIL:ryu@cj-c.com
# W W W :http://www.cj-c.com/
#----------------------------
# カウンタ表示方法 
# ログ名 sample で $I[1] の画像を利用し 5桁表示の場合
# 例 http://www.xxx.com/mc/m_count.cgi?sample+1+5


# ファイルの位置(http://〜のURL)
$file = "http://www.izu.biz/ensoleille/cgi-bin/count/count.cgi";

$met  = "POST";			# データ受け渡し形式(GET or POST)
$pass = "0717";			# ログ生成ページに入るパスワード
$log_d= "../../count/data/";			# ログ生成ディレクトリ(絶対・相対パスで 最後の / は省く)

# -----------------------------[GIF画像ディレクトリ設定]---*
# $I[0] は、デフォルトディレクトリです。
# 　特に設定しないとこのディレクトリの画像が表示されます。
# $I[*] の * を ログ名+* で指定すれば、
# 　その番号のディレクトリ画像が表示されます。
# 　例/ http://www.xxx.com/mc/m_count.cgi?yyy+2
# $I[*] は * を連番で指定していけばいくつでも作成できます。
# ---------------------------------------------------------*
$I[0] = "../../count/gif0";		# 相対・絶対パスで指定
$I[1] = "../../count/gif1";		# 最後のスラッシュは省く
		# 最後のスラッシュは省く
$DF   = 5;			# デフォルトの桁数
$locks= 0;			# ロック機能を使う?(0=NO 1=YES)
$IPC  = 0;			# 連続カウント防止(0=OFF 1=IPアドレスで 2=クッキーで)
$cday = 1;			# ↑2のときクッキー保存日数
$argv = 0;			# @ARGVが使えないサーバは1にしてみる
$R_MAX= 9;			# 乱数の最大値 0〜$R_MAX

$k_f= "ＭＳ Ｐゴシック";	# 基本フォント(環境による)
$k_s= "10pt";			# 基本フォントサイズ(ptは単位)
$ie_c="#E88C8E";		# リンク変化色(16進数 IEのみ変化)

#----[設定ここまで]-------------*

&d_code_;
if($argv){
	if($buffer=~ /\+/){($con,$gif,$fig)=split(/\+/,$access);}
	else{$ARGV[0]=$buffer;}
}
if($mode eq "make") { &make_; }
if($mode eq "make2"){ &make2_;}
if($mode eq "make3"){ &make3_;}
if($mode eq "m_n_") { &m_n_; }
if($mode eq "del")  { &del_; }
if($mode eq "all")  { &all_; }
if($buffer eq "")   { &make_;}

if($ARGV[0]){$con="$ARGV[0]";}
if($ARGV[1]){$gif="$ARGV[1]";}
if($ARGV[2]){$fig="$ARGV[2]";}

if($gif){$gi=$gif;}else{$gi=0;}
$dir="$I[$gi]";
if($fig){$fi=$fig;}else{$fi=$DF;}
if($fig eq "0"){$fi=0;}
if($con eq "Ram"){&ram_;}
$log = "$log_d/$con.dat";
unless(-e $log){&erimg_("NOFILE");exit;}
$lockfile= "$log_d/$con.loc";

$addr=$ENV{'REMOTE_ADDR'};
$FLAG=0;
if($IPC==2){&get_;}

if ($locks == 1) { &lock_; }
open(LOG,"$log");
$SET = <LOG>;
close(LOG);
($count,$Ip) = split(/:/,$SET);

if($gif eq "test"||($addr eq "$Ip" && $IPC==1)||($cook && $IPC==2)){$FLAG=0;}
else{$count++;$FLAG=1;}

if($FLAG){
	open(LOG,">$log");
	print LOG "$count:$addr:";
	close(LOG);
	if($IPC==2){&set_;}
}
if (-e $lockfile) { unlink($lockfile); }
&c_view;
exit;

#
# [ロック処理]
#
sub lock_ {
$lflag = 0;
foreach (1 .. 5) {
	unless (-e $lockfile) {
		open(LOCK,">$lockfile");
		close(LOCK);
		$lflag = 1;
		last;
	} else { sleep(1); }
}
if ($lflag == 0) {if(-e $lockfile){unlink($lockfile)};&er_("LOCK is BUSY!");}
}

#
# [GIF出力]
#
sub c_view {
$count += 0;
$count_  = sprintf(sprintf("%%0%dld", $fi), $count);
unless(-e "$dir/0.gif"){&erimg_("CIMG");exit;}
printf("Content-type: image/gif\n");
printf("\n");
for($i=0; $i<length($count_); $i++){$n=substr($count_,$i,1); push(@files,"$dir/$n.gif");}
binmode(STDOUT);
print &gifcat'gifcat(@files);
exit;
}
#
# [認証]
#
sub make_ {
&hed_("PASS INPUT");
print <<"_HTML_";
<center><table width=95\%><tr><th bgcolor=#A0D6A9>
<b>ログ生成ページ入室画面</b></th></tr></table>
<br>パスワードを入力してください。<br>
<form action="$file" method=$met>
<input type=hidden name=mode value=make2>
<input type=password name=pass size=8>
<input type=submit value="入室する">
</form></center>
_HTML_
&foot_;
}
#
# [管理画面]
#
sub make2_ {
if($FORM{'pass'} ne "$pass"){&er_("パスワードが違います!");}
&hed_("MANAGE MODE");
print <<"_HTML_";
<center><table width=95\%><tr><th bgcolor=#F8A9A5>カウンタ設定</th></tr></table></center>
<ul>・ログの生成、編集、削除ができます。<br>
・ログ名は英数字、アンダーバー(_)以外使用できないのでご注意下さい。<br>
・また、ログ名には乱数発生のコマンドのため Ram は利用できません。<br>
・大文字、小文字は別物として判断されます! ABC≠abc<br>
・<b><a href="$file?mode=all&pass=$FORM{'pass'}">ログ一覧を見る</a></b>
<ul>ManyCounterのログだと思われるファイルを表\示します(ログを作るディレクトリ対象)。</ul>
<hr><b>■ ログファイル生成</b><ul>
<form action="$file" method=$met>
<input type=hidden name=mode value="make3">
<input type=hidden name=pass value="$FORM{'pass'}">
作成ログ名:<input type=text name=name size=12> (必ず半角英数字で)<br>
開始カウント:<input type=text name=count size=12 value="0"><br><br>
<input type=submit value="ログ生成">
</form></ul>
<hr><b>■ カウント数を編集</b><ul>
<form action="$file" method=$met>
<input type=hidden name=mode value="m_n_">
<input type=hidden name=pass value="$FORM{'pass'}">
変更ログ名 :<input type=text name=name size=12><br><br>
<input type=submit value="カウント数変更画面へ">
</form></ul>
<hr><b>■ ログを削除</b><ul>
<form action="$file" method=$met>
<input type=hidden name=mode value="del">
<input type=hidden name=pass value="$FORM{'pass'}">
削除ログ名 :<input type=text name=name size=12><br><br>
<input type=submit value="ログ削除画面へ">
</form></ul></ul>
_HTML_
&foot_;
}
#
# [ログ生成]
#
sub make3_ {
if($FORM{'pass'} ne "$pass"){&er_("パスワードが違います！");}
if($name =~ /\W/) {&er_("ログ名に使用できるのは英数字とアンダーバーのみです!");}
if($name eq "Ram"){&er_("そのログ名は乱数発生時に使用するので使用不可です!");}
if($FORM{'count'} !~ /\d/){&er_("カウント数は半角数字を入れて下さい!");}
$log_f="$log_d\/$name\.dat";
if(-e $log_f){ &er_("ログ名 <b>$name</b> は既に使用しています!"); }
$new="$FORM{'count'}";
open(LOG,">$log_f") || &er_("Can't make $log_f");
print LOG "$new:0:";
close(LOG);

chmod (0666,$log_f);

&hed_("UP MODE");
print <<"_HTML_";
<center><table width=95\%>
<tr><th bgcolor=#C9D0FA>ログ生成完了</th></tr></table></center><ul>
<b>ログファイル生成処理は正常に完了しました。</b><br><hr>
<ul>
作成ログ名: <b>$name</b><br>
カウント数: <b>$FORM{'count'}</b><br>
</ul><hr>
<b>以下のタグを表\示したいところにコピーしてください。<br></b><ul>
&lt;!-- ここから --&gt;<br>
&lt;img src=&quot;$file?$name&quot;&gt;<br>
&lt;!-- ここまで --&gt;</ul><hr>
<b>以下に $FORM{'count'} の画像が表\示されれば成功です。</b><ul>
<img src="$file?$name+test+0"></ul>
<br>▲<a href="$file?mode=make2&pass=$FORM{'pass'}">管理画面にもどる</a></ul><br>
_HTML_
&foot_;
exit;
}
#
# [ログ編集]
#
sub m_n_ {
if($FORM{'pass'} ne "$pass"){&er_("パスワードが違います!");}
$log_f = "$log_d\/$name\.dat";
unless(-e $log_f){&er_("ログ <b>$name</b> が見つかりません!");}

open(LOG,"$log_f") || &er_("Can't open $log_f");
$SET = <LOG>;
close(LOG);
($count,$Ip)=split(/:/,$SET);

if ($take) {
	if($FORM{'count'} !~ /\d/){&er_("カウント数は半角数字を入れて下さい!");}
	$count="$FORM{'count'}";

	open(LOG,">$log_f") || &er_("Can't write $log_f");
	print LOG "$count:$Ip:";
	close(LOG);

	&hed_("EDIT END");
	print <<"_HTML_";
<center>
<table width=95\%><tr><th bgcolor=#E4C9E9>カウント数編集</th></tr></table></center><ul>
<b>編集は正常に完了しました。</b><ul>
編集ログ名: <b>$name</b><br>
カウント数: <b>$FORM{'count'}</b></ul><br>
*) 画像がブラウザのキャッシュに残っている場合、
それが削除されるまで以前のカウント数になりますのでご了承下さい。<br><br>
▲<a href="$file?mode=make2&pass=$FORM{'pass'}">管理画面にもどる</a></ul>
_HTML_
}else {
	&hed_("EDIT MODE");
	print <<"_HTML_";
<center><table width=100\%><tr><th bgcolor=#E4C9E9>カウント数編集</th></tr></table></center>
<ul><b>■ $name のカウントを修正します。</b><ul>
<form action="$file" method=$met>
<input type=hidden name=pass value="$FORM{'pass'}">
<input type=hidden name=mode value="m_n_">
<input type=hidden name=name value="$name">
<input type=hidden name=take value="1">
ログ <b>$name</b> のただいまのカウント数:<b>$count</b><br>
カウント数を: <input type=text name=count size=10 value="$count"> に変更<br><br>
<input type=submit value="カウント数変更">
</form></ul>▲<a href="$file?mode=make2&pass=$FORM{'pass'}">管理画面にもどる</a></ul>
_HTML_
}
&foot_;
exit;
}
#
# [ログ削除]
#
sub del_ {
if($FORM{'pass'} ne "$pass"){&er_("パスワードが違います!");}
$log_f = "$log_d\/$name\.dat";
unless (-e $log_f) { &er_("ログ <b>$name</b> が見つかりません!"); }

if ($take) {
	unlink($log_f);

	&hed_("DEL END");
	print <<"_HTML_";
<center><table width=95\%>
<tr><th bgcolor=#E3FEA7>ログ削除</th></tr></table></center><ul>
<b>ログファイル $name は削除されました。</b><br><br>
▲<a href="$file?mode=make2&pass=$FORM{'pass'}">管理画面にもどる</a></ul>
_HTML_
}else {
open(LOG,"$log_f") || &er_("Can't open $log_f");
$SET = <LOG>;
close(LOG);
($count,$Ip)=split(/:/,$SET);
&hed_("DEL MODE");
print <<"_HTML_";
<center><table width=95\%>
<tr><th bgcolor=#DBDBD9>ログ削除画面</th></tr></table></center><ul>
ログ <b>$name</b> を本当に削除しますか?<br>
カウント数: $count<br><br>
<form action="$file" method="get">
<input type=hidden name=name value="$name">
<input type=hidden name=pass value="$FORM{'pass'}">
<input type=hidden name=mode value="del">
<input type=hidden name=take value="1">
<input type=submit value="ログを削除"></form>
▲<a href="$file?mode=make2&pass=$FORM{'pass'}">管理画面にもどる</a></ul>
_HTML_
}
&foot_;
}
#
# [ヘッダ表示]
#
sub hed_ {
print "Content-type: text/html\n\n";
print <<"_HTML_";
<html><head>
<STYLE TYPE="text/css">
<!--
A{ text-decoration:none; }
A:hover{ color:$ie_c; text-decoration:underline; }
BODY,TD,TH{ font-family:"$k_f"; font-size:$k_s; }
-->
</STYLE>
<!--$ver-->
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=Shift_JIS">
<title>ManyCounter [$_[0]]</title>
</head>
<body text="#808080" bgcolor="#FEEABA" link="#8989E0" vlink="#80D08B">
_HTML_
}
#
# [デコード]
#
sub d_code_ {
if ($ENV{'REQUEST_METHOD'} eq "POST") {read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});}
else { $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;

	$FORM{$name} = $value;
}
$mode = $FORM{'mode'};
$name = $FORM{'name'};
$take = $FORM{'take'};
$con  = $FORM{'con'};
$fig  = $FORM{'fig'};
$gif  = $FORM{'gif'};
}
#
# [フッタ表示]
#
sub foot_ {
print <<"_HTML_";
<!--著作権表\示 削除しないでください-->
<hr width=95\%>
<center>- <a href="http://www.cj-c.com/" target=_top>ManyCounter</a> -</center>
</body></html>
_HTML_
exit;
}
#
# [エラー表示]
#
sub er_ {
&hed_("ERROR");
print "<center>ERROR - $_[0]</center>\n";
&foot_;
}
sub set_ { # クッキー発行
($secg,$ming,$hourg,$mdayg,$mong,$yearg,$wdayg,$ydayg,$isdstg)=gmtime(time + $cday*24*60*60);
$yearg += 1900;
if ($secg  < 10) { $secg  = "0$secg";  }
if ($ming  < 10) { $ming  = "0$ming";  }
if ($hourg < 10) { $hourg = "0$hourg"; }
if ($mdayg < 10) { $mdayg = "0$mdayg"; }
$month = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$mong];
$youbi = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')[$wdayg];
$date_gmt = "$youbi, $mdayg\-$month\-$yearg $hourg:$ming:$secg GMT";
$cook="cook\:1";
print "Set-Cookie: $con=$cook; expires=$date_gmt\n";
}
sub get_ { # クッキー取得
$cookies = $ENV{'HTTP_COOKIE'};
@pairs = split(/;/,$cookies);
foreach $pair (@pairs) {
	($name, $value) = split(/=/, $pair);
	$name =~ s/ //g;
	$DUMMY{$name} = $value;
}
@pairs = split(/,/,$DUMMY{"$con"});
foreach $pair (@pairs) {
	($name, $value) = split(/:/, $pair);
	$COOKIE{$name} = $value;
}
$cook = $COOKIE{'cook'};
}
#
# [乱数発生]
#
sub ram_ {
srand;
$count=int(rand($R_MAX));
&c_view;
}
#
# [エラー画像]
#
sub erimg_ {
print "Content-type: image/gif\n\n";
if($_[0] eq "NOFILE"){
	@pic=(
	"47","49","46","38","39","61","46","00","14","00","91","00","00","ff","33",
	"33","ff","ff","ff","00","00","00","00","00","00","2c","00","00","00","00",
	"46","00","14","00","00","02","c5","94","8f","a9","cb","ed","0f","a3","9c",
	"54","81","8b","05","ce","7a","83","e3","81","61","25","5d","89","69","98",
	"68","c7","a6","5f","0b","93","ce","ea","8a","b0","fa","b6","2b","2d","33",
	"de","f7","73","6d","6a","c4","60","ef","c1","43","29","5f","4b","9b","2e",
	"77","f4","41","9f","45","66","ae","19","8b","5a","42","3b","e0","d5","ca",
	"b9","4d","b5","a2","9f","f9","8c","4e","ab","d7","63","b2","bb","64","18",
	"c8","e7","f4","fa","20","40","c7","db","e7","fa","bd","5f","1e","10","18",
	"78","47","48","a7","11","f7","67","37","08","98","d8","97","a8","b8","e7",
	"38","70","28","f0","58","87","a7","97","b9","c8","a7","b8","28","e8","28",
	"89","09","88","47","69","99","57","28","ca","c8","79","ca","28","78","e9",
	"4a","98","1a","50","6a","aa","2a","da","07","7a","c9","29","a9","ba","7b",
	"27","48","5b","8b","9b","5a","d8","db","8b","b9","69","1c","5b","1c","6c",
	"9a","fb","1b","fa","39","9a","69","1c","8a","1a","d8","5c","ab","6d","99",
	"ac","8d","b0","0d","1e","ee","7d","50","00","00","3b"
	);
}elsif($_[0] eq "CIMG"){
	@pic=(
	"47","49","46","38","39","61","46","00","14","00","91","00","00","ff","33",
	"33","ff","ff","ff","00","00","00","00","00","00","2c","00","00","00","00",
	"46","00","14","00","00","02","c9","94","8f","a9","cb","ed","0f","a3","9c",
	"54","81","8b","05","ce","7a","83","e3","81","61","25","5d","89","69","98",
	"68","c7","a6","5f","0b","93","ce","ea","8a","b0","fa","b6","2b","2d","33",
	"de","f7","73","6d","6a","c4","60","ef","c1","43","29","5f","4b","9b","2e",
	"77","f4","41","9f","45","66","ae","19","8b","5a","42","3b","e0","d5","ca",
	"b9","4d","b5","a2","9f","f9","8c","4e","ab","d7","63","b2","bb","64","18",
	"c8","e7","74","7a","c0","5e","cf","07","f6","f9","f9","5d","ce","37","b0",
	"37","28","58","58","a7","11","d7","a7","f7","67","a8","c8","c8","e8","88",
	"a7","97","87","28","a0","38","f9","97","19","e8","c7","09","48","78","37",
	"98","59","07","ea","29","57","79","39","6a","48","0a","28","d9","48","a8",
	"6a","f7","4a","2a","7a","8a","da","39","db","c9","aa","db","08","9b","cb",
	"0a","4a","58","6b","eb","ba","ca","fb","e8","17","28","ea","5b","58","3c",
	"20","6c","0b","a9","09","e9","29","5a","bd","cb","cb","4c","ed","fc","32",
	"dc","ed","bd","e9","ad","88","10","4e","5e","6e","8e","50","00","00","3b"
	)
}
foreach (@pic) { 
	$data = pack('C*',hex($_));
	binmode(STDOUT);
	print "$data";
}
}
#
# [全ログ閲覧]
#
sub all_ {
if($FORM{'pass'} ne "$pass"){&er_("パスワードが違います!");}
$total=0;
&hed_("ALL LOG");
print<<_ALL_;
<center><table width=95\%><tr><th bgcolor=#FFFFFF>ログ一覧</th></tr></table></center>
<ul>・ログ生成ディレクトリからManyCounterのログと思われるファイルをピックアップし、
ログサイズとカウント数を表\示します。<br>
・ManyCounterのログであれば、ログ名をクリックする事によって正常に編集可能\です。<br>
・また、ログ名の横の [削除] をクリックすれば削除画面にも移動可能\です。<br><ul><br>
ログ名 (カウント数/ログサイズ) [削除]...で表\示しています。<br><br>
_ALL_
opendir(DIR,"$log_d");
while($file=readdir(DIR)){if($file ne ""){unshift(@filenames,$file);} }
closedir(DIR);
foreach $name (@filenames){
	if($name !~/.dat/){next;}
	$size =  -s "$log_d/$name";
	open(LOG,"$log_d/$name") || &er_("Can't open $log_d/$name");
	$SET = <LOG>;
	close(LOG);
	($count,$Ip)=split(/:/,$SET);
	$name=~ s/.dat//;
	print"<a href='$file?mode=m_n_&name=$name&pass=$FORM{'pass'}'>$name</a> ";
	print"($count/$size)";
	print" [<a href='$file?mode=del&name=$name&pass=$FORM{'pass'}'>削除</a>]<br>\n";
	$total += $size;
}
print "</ul><br><b>合計ログサイズ/$totalバイト</b></ul>\n";
&foot_;
}
