#!/usr/local/bin/perl #Web Count (2005/01/11) $ver = '1.05'; # #Copyright(C) Knight 2002-2005 #Mail ... support@web-liberty.net #Home ... http://www.web-liberty.net/ #――――― 設定項目 ―――――――――――――――――――――――― #――――― 基本設定 ――――――――――――――――――― #ログファイル $log_file = './count.log'; #ロックファイル $lock_file = './lock/count.lock'; #文字コード変換ライブラリ require './jcode.pl'; #アクセスをカウントしないホスト @no_count_list = ( '', '', '', '', '' ); #ホスト名取得時のgethostbyaddr関数の使用(0 … 使用しない / 1 … 使用する) $gethostbyaddr = 0; #――――― 外部アクセス記録の設定 ―――――――――――― #外部からのアクセスの記録(0 … 記録しない / 1 … 記録する) $access_record = 0; #アクセスログファイル $record_file = './record.log'; #アクセスログの最大保存数 $max_log = 1000; #リファラを記録しないファイル @no_record_file = ( 'http://your.page.addr/index.html', '', '', '', '', '' ); #リファラを記録しないリンク元 @no_record_referer = ( 'http://your.page.addr/', '', '', '', '', '' ); #――――― 設定項目終了 ―――――――――――――――――――――― ### メイン処理 &decode(); &get_data(); ### データ取得 sub get_data { if ($in{'file'} eq '') { $in{'file'} = $ENV{'HTTP_REFERER'}; } $date = time(); $host = $ENV{'REMOTE_HOST'}; $addr = $ENV{'REMOTE_ADDR'}; if ($host eq "" || $host eq $addr) { if ($gethostbyaddr == 1) { $host = gethostbyaddr(pack("C4", split(/\./, $addr)), 2) || $addr; } } if ($no_count_list[0] ne '') { foreach $list (@no_count_list) { if ($list ne '' && $host =~ /$list/i) { &dmyimg(); } } } &lock($lock_file); open(FILE, "$log_file") || &error("ログファイルを読み出せません。"); @logs = ; close(FILE); ($last, $ip, $key) = split(/\t/, shift(@logs)); if ($last eq $in{'file'} && $host eq $ip) { &unlock($lock_file); &dmyimg(); } local($sec, $min, $hour, $day) = localtime(time()); @new = (); $flag = 0; foreach (@logs) { chop($_); ($file, $count, $today, $yesterday) = split(/\t/); if ($in{'file'} eq $file) { $count++; if ($key == $day) { $today++; push(@new, "$file\t$count\t$today\t$yesterday\n"); } else { push(@new, "$file\t$count\t1\t$today\n"); } $flag = 1; } else { if ($key == $day) { push(@new, "$_\n"); } else { push(@new, "$file\t$count\t0\t$today\n"); } } } if ($flag == 0 && $in{'file'} ne '') { push(@new, "$in{'file'}\t1\t1\t0\n"); } unshift(@new, "$in{'file'}\t$host\t$day\n"); open(FILE, ">$log_file") || &error("ログファイルに書き込めません。"); print FILE @new; close(FILE); if ($access_record == 1) { $flag = 0; if ($in{'file'} eq '' || $in{'referer'} eq '') { $flag = 1; } if ($flag == 0) { foreach (@no_record_file) { if ($_ ne '' && $in{'file'} eq $_) { $flag = 1; } } foreach (@no_record_referer) { if ($_ ne '' && $in{'referer'} =~ /$_/) { $flag = 1; } } } if ($flag == 0) { open(FILE, "$record_file") || &error("アクセスログファイルを読み出せません。"); @record = ; close(FILE); $line = "$date\t$in{'file'}\t$in{'referer'}\t$host\n"; unshift(@record, $line); splice(@record, $max_log); open(FILE, ">$record_file") || &error("アクセスログファイルに書き込めません。"); print FILE @record; close(FILE); } } &unlock($lock_file); &dmyimg(); } ### デコード sub decode { ($file, $referer) = split(/&/, $ENV{'QUERY_STRING'}, 2); $referer =~ tr/+/ /; $referer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg; $referer =~ s/\%7e/\~/gi; &jcode'convert(*referer, 'sjis'); foreach ($file, $referer) { $_ =~ s/&/&/g; $_ =~ s//>/g; $_ =~ s/"/"/g; } $in{'file'} = $file; $in{'referer'} = $referer; return; } ### エラー出力 sub error { local($_) = @_; die "Error : $_"; &unlock($lock_file); &dmyimg(); } ### 画像出力 sub dmyimg { @dmy = ( '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 (@dmy) { $data = pack('C*',hex($_)); print $data; } exit(); } ### ファイルロック sub lock { local($lock_file) = @_; local $flag = 0; foreach (1 .. 5) { if (-e $lock_file) { if (time() > (stat($lock_file))[9] + 60) { &unlock($lock_file); next; } sleep(1); } else { open(LOCK, ">$lock_file") || &error("ロックファイルが作成できません。"); close(LOCK); $flag = 1; last; } } if ($flag == 0) { &error("ファイルがロックされています。"); } return; } ### ファイルロック解除 sub unlock { local($_) = @_; unlink($_); return; }