#!/usr/bin/perl


$days = 7; #何日前から統計を取るか。整数で記入。
$title = 'EASY ACCESS_LOG';	#タイトル

$password = 'kugaroot';	#パスワード（管理者画面用）

#記録保存ファイル。他のディレクトリに置く場合は相対パス記入。
$file = "log.txt";	#同じディレクトリの場合はそのままで可。
#イメージファイル。他のディレクトリに置く場合は相対パス記入。
$img = "../img/count.gif";	#同じディレクトリの場合はそのままで可。
#=====================================================================
# 初期設定が必要なのはここまでです。
#　（以下は変更の必要はありません）
#=====================================================================

$time = time;
$days = int($days);
$days_sec = $days * 60 * 60 * 24;
$days_hour = $days * 24;
$delete = $time - $days_sec;

#時間の取得
@jikan = localtime;

$jikan[4] ++;

if ($ENV{'REQUEST_METHOD'} eq "POST") {
	read(STDIN, $formdata, $ENV{'CONTENT_LENGTH'});
} else { $formdata = $ENV{'QUERY_STRING'}; }

@pairs = split(/&/,$formdata);
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{'action'};
$psw = $FORM{'psw'};

#条件分岐
if($mode eq 'view'){
	&view_html;
}elsif($mode eq 'admin'){
	if($psw eq "$password"){
		&admin;
	}else{
		&view_html;
	}
}else{
	&add_log;
}

#新しいログをファイルに書き込むサブルーチン
sub add_log {
	&shukei;
	@data_new = reverse(@data_new);
	@line1 = split(/\,/,$data_new[0]);
	push(@data_new,$new_soukei);
	@data_new = reverse(@data_new);
	$new_total = $line1[0] + 1;
	$year = 1900 + $jikan[5];
	$remote_addr = $ENV{'REMOTE_ADDR'};
	$remote_host = ((gethostbyaddr(pack('C4',split(/\./,$remote_addr)),2))[0]);
	if($remote_host eq ''){$remote_host = $remote_addr;}
	$new_log = "$new_total,$year,$jikan[4],$jikan[3],$jikan[2],$time,$jikan[1],$remote_host,$ENV{'HTTP_USER_AGENT'}\n";
	push(@data_new,$new_log);

	open(LOG,">$file");
	flock(LOG,2);
	print LOG @data_new;
	flock(LOG,8);
	close(LOG);

	open(IMG,"$img");
	@data_gif = stat($img);
	$byte = $data_gif[7];
	
	print "Content-type: image/gif\n";
	print "Content-length: $byte\n\n";
	print <IMG>;
	close(IMG);
}

#集計結果をHTML出力するサブルーチン
sub view_html {
	&shukei;
	$n = $days;
	while($n > 0){
		$hi = $n * 60 * 60 * 24;
		@times = localtime($time - $hi);
		$kako_hi = $times[3]; #$days前の日付
		$kako_mon = $times[4];
		$kako_mon ++;
		if($keep ne ''){
			$keep = "$keep,$kako_hi";
			$keep_mon = "$keep_mon,$kako_mon";
		}elsif($keep eq ''){
			$keep = $kako_hi;
			$keep_mon = $kako_mon;
		}
		$n --;
	}
	$keep = "$keep,$jikan[3]";
	$keep_mon = "$keep_mon,$jikan[4]";
	@hizuke = split(/\,/,$keep);
	@tsuki = split(/\,/,$keep_mon);
	print "Content-type: text/html\n\n";
	print "<HTML><HEAD><meta http-equiv=\"Content-Type\" content=\"text/html; charset=shift_jis\"><TITLE>$title</TITLE></HEAD>\n";
	print "<BODY bgcolor=\"#F7F7E0\">\n";
	print "<H2><FONT color=\"#0000ff\">$title</FONT></H2>\n";
	print "<TABLE border=1>\n";
	print "<TR><TH>総計</TH><TD align=center>本日</TD><TD align=center>昨日</TD>\n";
	print "<TD align=center>今月</TD><TD align=center>先月</TD></TR>\n";
	print "<TR><TH>$soukei</TH><TD align=center>$tod_count</TD><TD align=center>$yst_count</TD>\n";
	print "<TD align=center>$this_count</TD><TD align=center>$last_count</TD></TR>\n";
	print "</TABLE>\n";
	print "<P><FONT color=\"#0000ff\">$days_hour</FONT>時間前\n";
	print "から現在までのアクセス状況です</P>\n";
	print "<TABLE border=1>\n";
	print "<TR><TH>月／日</TH><TH>時刻</TH><TH>数</TH>\n";
	print "<TH>グラフ表\示</TH></TR>\n";
	$nokori = 'yes';

	$new_hour = $jikan[2];
	$hour_puls = 0;
	$k = 0;
	$d = 0;
	$new_count = @data_new;
	$keep_new_count = $new_count;
	$new_days_hour = $days_hour + 1;
	while($new_days_hour > 0){
		$kiroku = 0;
		while($new_count > 0){
			($total,$log_year,$log_mon,$log_day,$log_hour,$log_time) = split(/\,/,$data_new[$d]);

			if(($hizuke[$k] eq $log_day) && ($new_hour eq $log_hour)){
				$kiroku++;
			}
			$d ++;
			$new_count --;
		}

		print "<TR><TD>$tsuki[$k]／$hizuke[$k]</TD><TD>$new_hour</TD><TD>$kiroku</TD>\n";
		$graph = "*" x $kiroku;
		print "<TD><FONT color=\"#0000ff\">$graph</FONT></TD></TR>\n";
		$d = 0;
		$new_count = $keep_new_count;
		$hour_puls ++;
		if(($delete eq $hour_puls) && ($nokori eq 'yes')){
			$new_hour = 0;
			$k ++;
			$nokori = 'no';
		}elsif(($new_hour eq 23) && ($nokori eq 'yes')){
			$new_hour = 0;
			$k ++;
			$nokori = 'no';
		}elsif(($new_hour eq 23) && ($nokori eq 'no')){
			$new_hour = 0;
			$k ++;
		}else{
			$new_hour ++;
		}
		$new_days_hour --;
	}
	print "</TABLE>\n";
	print "<P><FONT size=+2><B><A HREF=\"javascript:history.back()\">戻る</A></B></P>\n";
	#以下13行はコーピーライトですので、削除しないで下さい
print <<EOM;
<TABLE width="100%">
  <TR>
    <TD align="left">
    <FORM action="ezlog.cgi" method="POST">
	<INPUT type="hidden" name="action" value="admin">
<INPUT type="submit" value="管理用"><INPUT type="password" name="psw" size="10">
    </FORM>
</TD>
</TR>
</TABLE>
EOM
	print "</BODY>\n</HTML>\n";
}

#アクセス数を時間毎に区切って集計するサブルーチン
sub shukei {
	open(LOG,"$file");
	flock(LOG,2);
	@data = <LOG>;
	flock(LOG,8);
	close(LOG);

	$mday = $jikan[3];
	$mon = $jikan[4];
	($soukei,$log_mday,$tod_count,$yst_count,$log_mon,$this_count,$last_count) = split(/\,/,$data[0]);

	if($mode ne 'view'){
		$soukei ++;
		if($mday == $log_mday){
    		$tod_count++;
		}else{
    		$yst_count = $tod_count;
    		$tod_count = 1;
		}

		if($mon == $log_mon){
   			$this_count++;
		}else{
    		$last_count = $this_count;
    		$this_count = 1;
		}

		$new_soukei = "$soukei,$mday,$tod_count,$yst_count,$mon,$this_count,$last_count,\n";
	}
	$count = @data;
	$i = 0;
	while($count > 0){
		($total,$log_year,$log_mon,$log_day,$log_hour,$log_time) = split(/\,/,$data[$i]);
		if($log_time > $delete){
			@data_new = (@data_new,$data[$i]);
		}
		$i ++;
		$count --;
	}
}

#管理者用画面を出力するサブルーチン
sub admin{
	open(TXT,"$file");
	flock(TXT,2);
	@DATA = <TXT>;
	flock(TXT,8);
	close(TXT);
	$count = @DATA;
	$count--;
	$i = 1;
	print "Content-type: text/html\n\n";
	print "<HTML>\n<HEAD>\n<HEAD>\n<TITLE>\n管理者用画面\n</TITLE>\n</HEAD>\n";
	print "<BODY bgcolor=\"seashell\">\n<H3>管理者用画面</H3>\n";
	print "<P align=\"right\"><A href=\"javascript:history.back()\">戻る</A></P>\n";
	print "<P><FONT color=\"#0000ff\">$days_hour</FONT>時間前\n";
	print "から現在までのアクセス状況です</P>\n";
print <<EOM;
<TABLE border="1">
  <TR>
    <TH>No.</TH>
    <TH>月</TH>
    <TH>日</TH>
    <TH>時</TH>
    <TH>分</TH>
    <TH>リモートホスト（サーバー名）</TH>
    <TH>ユーザーエージェント（ブラウザ名）</TH></TR>
EOM
	while($count > 0){
		@line = split(/\,/,$DATA[$i]);
print <<EOM;
  <TR>
    <TD>$line[0]</TD>
    <TD>$line[2]</TD>
    <TD>$line[3]</TD>
    <TD>$line[4]</TD>
    <TD>$line[6]</TD>
    <TD>$line[7]</TD>
    <TD>$line[8]</TD>
    </TR>
EOM
		$i++;
		$count--;
	}

	print "</TABLE>\n<BODY>\n</HTML>\n";
}

	

