#!/usr/local/bin/perl #Web Analyze (2005/07/13) $ver = '2.03'; # #Copyright(C) Knight 2002-2005 #Mail ... support@web-liberty.net #Home ... http://www.web-liberty.net/ #――――― 設定項目 ―――――――――――――――――――――――― #初期設定ファイル require './analyze.ini'; #――――― 設定項目終了 ―――――――――――――――――――――― ### メイン処理 &decode(); &record_data(); &output_result(); ### データ記録 sub record_data { $flag = 0; foreach (@no_record_referer) { if ($_ ne '' && $in{'referer'} =~ /$_/) { $flag = 1; } } if ($flag == 1) { return; } $date = time(); $agent = $ENV{'HTTP_USER_AGENT'}; if ($download_mode != 0 && $download{"$ENV{'QUERY_STRING'}"} ne '') { $js_flag = ''; $http_referer = $in{'url'}; } elsif ($ENV{'QUERY_STRING'} eq '' || $in{'url'} ne '') { $js_flag = 0; $http_referer = $in{'url'}; } else { $js_flag = 1; $http_referer = $ENV{'HTTP_REFERER'}; } $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_record_host[0] ne '') { $flag = 0; foreach $list (@no_record_host) { if ($list ne '' && $host =~ /$list/i) { $flag = 1; } } if ($flag == 1) { return; } } &lock($lock_file); ($sec, $min, $hour, $day, $mon, $year, $week) = localtime(time()); $log_name = sprintf("%04d%02d%02d", $year + 1900, $mon + 1, $day); if (-e "$log_dir$log_name$log_ext") { open(FILE, "$log_dir$log_name$log_ext") || &error("ログファイルを読み出せません。"); @logs = ; close(FILE); } else { opendir(DIR, "$log_dir") || &error("ログファイル保存ディレクトリを読み出せません。"); @dir = readdir(DIR); closedir(DIR); @dir = sort {$b <=> $a} (@dir); if ($sendmail_mode == 1 && $dir[0] =~ /^\d+(\.\w+)$/ && $1 eq $log_ext) { &sendmail($log_dir, $dir[0]); } @log_file = (); $i = 1; foreach (@dir) { if ($_ =~ /^\d+(\.\w+)$/ && $1 eq $log_ext && $i >= $keep_days) { unlink("$log_dir$_"); } $i++; } @logs = (); } $flag = 0; foreach (@logs) { ($time, $ip) = (split(/\t/))[0, 6]; if (time() - $time > $session_time * 60) { last; } if ($host eq $ip) { $flag = 1; last; } } if ($flag == 1) { $double_flag = 1; } else { $double_flag = 0; } if ($visit_track_mode == 1 || $visit_count_mode == 1) { %cookie = &get_cookie($cookie_id); if ($no_record_cookie[0] ne '') { $flag = 0; foreach $list (@no_record_cookie) { if ($list ne '' && $cookie{'id'} eq $list) { $flag = 1; } } if ($flag == 1) { &unlock($lock_file); return; } } } if ($visit_track_mode == 1) { if ($cookie{'id'} eq '') { srand(time + $$); $cookie{'id'} = substr(crypt(time(), pack('CC', int(rand(26) + 65), int(rand(10) + 48))), 0, 5) . time(); } } if ($visit_count_mode == 1) { $count = $cookie{'count'}; $last_time = $cookie{'last'}; if ($count eq '') { $count = 1; } else { $count++; } if ($session_time == 0 || $count == 1 || $last_time eq '' || time() - $last_time > $session_time * 60) { $cookie{'count'} = $count; $cookie{'last'} = time(); } else { $count = ''; $last_time = ''; } } else { $count = ''; $last_time = ''; } if ($visit_track_mode == 1 || $visit_count_mode == 1) { &set_cookie(*cookie, $cookie_id, $hold_days); } $line = "$date\t$in{'referer'}\t$agent\t$js_flag\t$in{'screen'}\t$in{'color'}\t$host\t$cookie{'id'}\t$double_flag\t$count\t$last_time\t$http_referer\n"; unshift(@logs, $line); open(FILE, ">$log_dir$log_name$log_ext") || &error("ログファイルに書き込めません。"); print FILE @logs; close(FILE); if ($counter_mode == 1 && $double_flag == 0) { &count_up(); } &unlock($lock_file); return; } ### 結果出力 sub output_result { if ($download_mode != 0 && $download{"$ENV{'QUERY_STRING'}"} ne '') { if ($download_mode == 1) { if ($ENV{'PERLXS'} eq 'PerlIS') { print "HTTP/1.0 302 Temporary Redirection\r\n"; print "Content-type: text/html\n"; } print "Location: $in{'url'}\n\n"; exit(); } else { print <<"_HTML_"; Content-Type: text/html ファイルのダウンロード

ファイルのダウンロード

自動的にファイルがダウンロードされない場合、以下のURLをクリックしてダウンロードしてください。

_HTML_ exit(); } } else { &dmyimg(); } } ### メール送信 sub sendmail { local($file_dir, $file_name) = @_; $encoded_subject = &mail64encode($mail_subject); $mail_body = "アクセス解析ログ $file_name を送信します。"; foreach $mailto (@mailto) { if ($mailto eq '') { next; } $interval = 'WebAnalyze' . time(); open(MAIL,"| $sendmail -t") || &error("メールが送信できません。"); print MAIL "X-Mailer: Web Analyze ver $ver\n"; print MAIL "To: $mailto\n"; print MAIL "From: \"Web Analyze\" <$mailto[0]>\n"; print MAIL "Subject: $encoded_subject\n"; print MAIL "Content-Type: multipart/mixed; boundary=\"$interval\"\n\n"; print MAIL "--$interval\n"; print MAIL "Content-Transfer-Encoding: 7bit\n"; print MAIL "Content-Type: text/plain; charset=iso-2022-jp\n\n"; foreach (split(/\n/, $mail_body)) { &jcode'convert(*_, 'jis' ,'sjis'); print MAIL "$_\n"; } print MAIL "--$interval\n"; print MAIL "Content-Type: application/octet-stream; name=\"$file_name\"\n"; print MAIL "Content-Transfer-Encoding: X-uuencode\n"; print MAIL "Content-Disposition: attachment; filename=\"$file_name\"\n\n"; open(IN, "$file_dir$file_name"); print MAIL &uuencode(join('', ), $file_name); close(IN); print MAIL "--$interval--\n"; close(MAIL); } return; } ### アクセスカウンタカウントアップ sub count_up { open(COUNT, "$count_log") || &error("カウントログファイルを読み出せません。"); $data = ; close(COUNT); local($sum, $today, $yesterday, $key) = split(/\t/, $data); local($sec, $min, $hour, $day) = localtime(time()); if ($key == $day) { $today++; } else { $yesterday = $today; $today = 1; } $sum++; $data = "$sum\t$today\t$yesterday\t$day"; open(COUNT, ">$count_log") || &error("カウントログファイルに書き込めません。"); print COUNT $data; close(COUNT); if ($count_output == 1) { if ($count_view == 1) { $sum =~ s/(.)/$1/g; $today =~ s/(.)/$1/g; $yesterday =~ s/(.)/$1/g; } open(FILE, ">$sum_count_js") || &error("総カウントをJSファイルに書き込めません。"); print FILE "document.write('$sum');"; close(FILE); open(FILE, ">$today_count_js") || &error("本日のカウントをJSファイルに書き込めません。"); print FILE "document.write('$today');"; close(FILE); open(FILE, ">$yesterday_count_js") || &error("昨日のカウントをJSファイルに書き込めません。"); print FILE "document.write('$yesterday');"; close(FILE); } return; } ### デコード sub decode { if ($download_mode != 0 && $download{"$ENV{'QUERY_STRING'}"} ne '') { $url = $download{"$ENV{'QUERY_STRING'}"}; $screen = ''; $color = ''; $referer = $ENV{'HTTP_REFERER'}; } elsif ($ENV{'QUERY_STRING'} =~ /^https?:\/\/[\w\.\~\-\/\?\&\#\+\=\:\;\@\%]+$/) { $url = $ENV{'QUERY_STRING'}; $screen = ''; $color = ''; $referer = ''; } else { $url = ''; ($screen, $color, $referer) = split(/&/, $ENV{'QUERY_STRING'}, 3); $referer =~ tr/+/ /; $referer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg; #&jcode'convert(*referer, 'sjis'); $referer = jcode($referer)->sjis; } foreach ($url, $screen, $color, $referer) { $_ =~ s/&/&/g; $_ =~ s//>/g; $_ =~ s/"/"/g; } $in{'url'} = $url; $in{'screen'} = $screen; $in{'color'} = $color; $in{'referer'} = $referer; return; } ### エラー出力 sub error { local($_) = @_; die "Error : $_"; &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; } ### BASE64エンコード(参考:とほほのWWW入門 ... http://www.tohoho-web.com/) sub mail64encode { local($_) = @_; &jcode'convert(*_, "jis"); $_ =~ s/\x1b\x28\x42/\x1b\x28\x4a/g; $_ = &base64encode($_); return("=?iso-2022-jp?B?$_?="); } sub base64encode { local($_) = @_; local $base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; local($xx, $yy, $zz, $i); $xx = unpack("B*", $_); for ($i = 0; $yy = substr($xx, $i, 6); $i += 6) { $zz .= substr($base, ord(pack("B*", "00" . $yy)), 1); if (length($yy) == 2) { $zz .= "=="; } elsif (length($yy) == 4) { $zz .= "="; } } return($zz); } ### 添付ファイルエンコード sub uuencode { local($data, $name) = @_; local $result; while ($data =~ s/^((.|\n){45})//) { $result .= pack('u', $&); } if ($data ne '') { $result .= pack('u', $data); } $result =~ s/`/ /g; $result = "begin 644 $name\n$result \nend\n"; return $result; } ### クッキー関連の処理 sub get_cookie { local($cookie_id) = @_; local %all_cookies = (); local %cookie = (); foreach (split(/; /, $ENV{'HTTP_COOKIE'})) { local($key, $value) = split(/=/); $all_cookies{"$key"} = $value; } foreach (split(/&/, $all_cookies{"$cookie_id"})) { local ($key, $value) = split(/:/); $value =~ s/&/&/g; $value =~ s//>/g; $value =~ s/"/"/g; $cookie{&unescape($key)} = &unescape($value); } return %cookie; } sub set_cookie { local(*cookie, $cookie_id, $hold_days) = @_; if (time() > $cookie{'refresh'} + 60 * 60 * 24 * 30) { $cookie{'refresh'} = time(); } local @pairs = (); foreach (sort keys %cookie) { push(@pairs, &escape($_) . ':' . &escape($cookie{"$_"})); } local $new_cookie = join('&', @pairs); local $date = &gmt_date(time + 60 * 60 * 24 * $hold_days); if ($new_cookie ne $all_cookies{"$cookie_id"}) { print "Set-Cookie: $cookie_id=$new_cookie; expires=$date\n"; } return; } sub escape { local($_) = @_; $_ =~ s/([&:;=%\x00-\x21])/sprintf("%%%02X", unpack('C',$1))/ge; return $_; } sub unescape { local($_) = @_; $_ =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('C', hex($1))/ge; return $_; } sub gmt_date { local($_) = @_; local($sec, $min, $hour, $day, $mon, $year, $wday) = gmtime($_); local @week = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); local @month = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); return sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT", $week[$wday], $day, $month[$mon], $year + 1900, $hour, $min, $sec); }