= count_digit_length) $digit_length = 0; # number of zeroes to prefix the count # (used when $digit_length < count_digit_length) $digit_pad = 1; # show digits in what language? # (used when showing digits as text) $arabic_count = 1; $chinese_count = 0; $roman_count = 0; if ($arabic_count) { $bold = 0; $italic = 0; $cnt_color = '#ff0000'; $cnt_face = 'Comic Sans MS'; $cnt_size = '+1'; } elseif ($chinese_count) { $bold = 1; $italic = 0; $cnt_color = '#ff0000'; $cnt_face = ''; $cnt_size = '+1'; } elseif ($roman_count) { $bold = 0; $italic = 0; $cnt_color = '#ff0000'; $cnt_face = 'Comic Sans MS'; $cnt_size = '+1'; } # digit images directory name & file extension # directory can use absolute or relative path # absolute paths start with "http://", "https://" or "/" # all other paths are considered relative (to main script directory) # (used when showing digits as images) $img_dir = 'digit'; $img_ext = 'gif'; # individual digit image width & height $img_width = 16; $img_height = 21; # digit images text alignment # e.g. absmiddle, top, middle, bottom $img_align = 'absmiddle'; ########################################################################### # statistics visible? $visible_stat = 1; # statistics page window name # use empty string for same window (as count page) $stat_frame = '_blank'; # statistics summary visible? # statistics detail visible? $summary_stat = 1; $detail_stat = 1; # statistics background colours $back_col_type = 'yellow'; $back_col_head = 'lightblue'; $back_col_body = 'lightcyan'; ########################################################################### # main programme ########################################################################### $agent_stat = array(); # create initial data files during first run if (! file_exists($vst_file)) { $vst_fp = fopen($vst_file, 'w') or die("Can't open $vst_file\n"); flock($vst_fp, 2); fwrite($vst_fp, '0.0.0.0|0'); fclose($vst_fp); } if (! file_exists($cnt_file)) { $cnt_fp = fopen($cnt_file, 'w') or die("Can't open $cnt_file\n"); flock($cnt_fp, 2); fwrite($cnt_fp, '0'); fclose($cnt_fp); } # run script if (getenv('QUERY_STRING') == '') { takeLog(); # take log } elseif (strtolower(getenv('QUERY_STRING')) == 'stat') { viewStat(); # view statistics } else { # exit when script is called with invalid parameter print '[parameter invalid]'; } ########################################################################### # functions ########################################################################### function takeLog() { global $script_url, $vst_file, $cnt_file, $log_file; global $visible_count; global $digit_type, $digit_length, $digit_pad; global $arabic_count, $chinese_count, $roman_count; global $bold, $italic, $cnt_color, $cnt_face, $cnt_size; global $img_dir, $img_ext, $img_width, $img_height, $img_align; global $visible_stat, $stat_frame; # do access log if (handleListedIP() || isReload()) { # no logging needed $cnt_fp = fopen($cnt_file, 'r') or die("Can't open $cnt_file\n"); $cnt = fread($cnt_fp, filesize($cnt_file)); $cnt = chop($cnt); fclose($cnt_fp); } else { # logging needed # process last-visit data $vst_fp = fopen($vst_file, 'w') or die("Can't open $vst_file\n"); flock($vst_fp, 2); $tm = time(); fwrite($vst_fp, getenv('REMOTE_ADDR')."|$tm"); fclose($vst_fp); # process count data $cnt_fp = fopen($cnt_file, 'r+') or die("Can't open $cnt_file\n"); flock($cnt_fp, 2); $cnt = fread($cnt_fp, filesize($cnt_file)); $cnt = chop($cnt); $cnt++; rewind($cnt_fp); fwrite($cnt_fp, $cnt); ftruncate($cnt_fp, ftell($cnt_fp)); fclose($cnt_fp); # process log data $log_fp = fopen($log_file, 'a') or die("Can't open $log_file\n"); flock($log_fp, 2); $aTime = localtime($tm, 1); $iY = $aTime['tm_year']+1900; $iM = $aTime['tm_mon']+1; $iM = ($iM>=10?$iM:"0$iM"); $iD = $aTime['tm_mday']; $iD = ($iD>=10?$iD:"0$iD"); $iHH = $aTime['tm_hour']; $iHH = ($iHH>=10?$iHH:"0$iHH"); $iMM = $aTime['tm_min']; $iMM = ($iMM>=10?$iMM:"0$iMM"); $iSS = $aTime['tm_sec']; $iSS = ($iSS>=10?$iSS:"0$iSS"); $logTime = "$iY-$iM-$iD $iHH:$iMM:$iSS"; if (gethostbyaddr(getenv('REMOTE_ADDR'))) { $logHost = gethostbyaddr(getenv('REMOTE_ADDR')); } else { $logHost = '[Unknown]'; } if (getenv('HTTP_USER_AGENT')) { $logAgent = getenv('HTTP_USER_AGENT'); } else { $logAgent = '[Unknown]'; } fwrite($log_fp, "$logTime|$logHost|$logAgent\n"); fclose($log_fp); } # show output $html_out = ''; if ($visible_count) { # pad zero(es) to the count # (used when showing text digits in Arabic or image digits) if (($digit_type == 0) && $arabic_count || ($digit_type == 1)) { if ($digit_length >= strlen($cnt)) { $digit_pad = $digit_length - strlen($cnt); } for ($i=0; $i<$digit_pad; $i++) { $cnt = '0' . $cnt; } } if ($digit_type == 0) { if (! $arabic_count) { if ($chinese_count) { $cnt = arabic2chinese($cnt); } elseif ($roman_count) { $cnt = arabic2roman($cnt); } } } elseif ($digit_type == 1) { # check if relative path is used for digit images directory if (! preg_match('@^(http://|https://|/)@', $img_dir)) { $img_url = preg_replace('@(.*)/.*@', '\\1', $script_url); $img_dir = "$img_url/$img_dir"; } } if ($visible_stat) { if ($stat_frame) { # show statistics page in given window $html_out .= ""; } else { # show statistics page in same window $html_out .= ""; } } if ($digit_type == 0) { # show count as text if ($cnt_color || $cnt_face || $cnt_size) { $html_out .= ' $agent_stat[$b]) { return(-1); } elseif ($agent_stat[$a] < $agent_stat[$b]) { return(1); } else { if ($a > $b) { return(-1); } elseif ($a < $b) { return(1); } else { return(0); } } } # handle listed ip handleListedIP(); # return if no stat or stat invisible if ((! file_exists($log_file)) || !$visible_stat || !$summary_stat && !$detail_stat) { print '[statistics not available]'; return(0); } # get count file data $cnt_fp = fopen($cnt_file, 'r') or die("Can't open $cnt_file\n"); $cnt_no = fread($cnt_fp, filesize($cnt_file)); $cnt_no = chop($cnt_no); fclose($cnt_fp); # get log file data $log_fp = fopen($log_file, 'r') or die("Can't open $log_file\n"); for ($log_no=0; ! feof($log_fp); $log_no++) { $tmp = preg_split('/\|/', fgets($log_fp, 256)); $time[$log_no] = $tmp[0]; $host[$log_no] = $tmp[1]; $agent[$log_no] = chop($tmp[2]); if ($agent[$log_no]) { $agent_stat[$agent[$log_no]]++; } } $log_no--; fclose($log_fp); # get count offset $off_no = $cnt_no - $log_no; # output stat report print "\n\n"; print "Statistics\n\n"; print "\n"; if ($summary_stat) { print "\n"; print "\n"; print "
Log Summary
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; $agent_stat_keys = array_keys($agent_stat); usort($agent_stat_keys, "doSort"); foreach ($agent_stat_keys as $key) { print "\n"; print "\n"; print "\n"; print "\n"; } print "\n"; print "\n"; print "\n"; print "\n"; print "
AgentCount
$key$agent_stat[$key]
Total$log_no
\n\n"; } if ($summary_stat && $detail_stat) { print "


\n\n"; } if ($detail_stat) { print "\n"; print "\n"; print "
Log Detail
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; for ($i=0; $i<$log_no; $i++) { print "\n"; printf("\n", $i+1+$off_no); print "\n"; print "\n"; print "\n"; print "\n"; } print "
 TimeHostAgent
%d$time[$i]$host[$i]$agent[$i]
\n"; } print "\n\n"; print "\n"; } function handleListedIP() { global $white_ip_list, $black_ip_list; global $visible_count, $visible_stat, $summary_stat, $detail_stat; $this_ip = getenv('REMOTE_ADDR') . '.'; foreach ($white_ip_list as $ip) { if (preg_match("/^$ip\./", $this_ip)) { # override default for white-listed ip $visible_count = 1; $visible_stat = 1; $summary_stat = 1; $detail_stat = 1; return(1); } } foreach ($black_ip_list as $ip) { if (preg_match("/^$ip\./", $this_ip)) { # override default for black-listed ip $visible_count = 0; $visible_stat = 0; $summary_stat = 0; $detail_stat = 0; return(2); } } return(0); } function isReload() { global $vst_file; global $anti_reload_period; $vst_fp = fopen($vst_file, 'r') or die("Can't open $vst_file\n"); $vst = preg_split('/\|/', fread($vst_fp, filesize($vst_file))); $ip_last = $vst[0]; $tm_last = chop($vst[1]); fclose($vst_fp); $tm_now = time(); $min_diff = ($tm_now-$tm_last)/60; # return true if current IP is the same as last IP and within anti-reload # period if ((getenv('REMOTE_ADDR')==$ip_last)&&($min_diff<=$anti_reload_period)) { return(1); } else { return(0); } } function arabic2chinese($in) { $d = '零'; $mm = array('','萬','億','兆'); # return 0 if input is all 0 if (! intval($in)) { return($d); } # construct chinese characters, in groups of 4 digits from the right for ($i=0,$s='',$out=''; $i