#!/usr/bin/perl
use GD;

# BS Counter
# Version 0.1.0
# Copyright 1999-2002 Brian Stanback.
# http://www.stanback.net

# This software is protected under the GNU General Public License (see LICENSE)
# If you use this script I wold appreciate a link back to my site.

# Please see the README document for configuration and installation help

#########################
# Declare the variables #
#########################

@allowed = ("sophokles.dk");
 # Sites allowed to use the counter.

$digits_dir = "/hsphere/local/home/sophok/sophokles.dk/cp/images/digits/";
 # Directory where png digit images are located.

$error = "/cp/images/digits/error.png";
 # Image displayed if domain is forbidden.

$pbar = "/cp/images/digits/pbar.png";
 # Url to the percent bar image. (1x8 px)

$pbar2 = "/cp/images/digits/pbar2.png";
 # Url to the res:xt of the percent bar. (1x8 px)

$pcap = "/cp/images/digits/pcap.png";
 # Url to the top of the percent bar image. (7x8 px)

$data_dir = "./data/";
 # Directory where hit logs are stored.

$reloads = 0;
 # Block counter reloads. (1 = yes, 0 = no);

#################################################
######### Don't change anything below ###########
#################################################
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
$mon++; @days = ('xxx','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); $year = (2000+($year-100)); $cdate = "$days[$mon] $mday, $year";
$min = "0$min" if length($min) < 2; $sec = "0$sec" if length($sec) < 2; $ctime = "$hour:$min:$sec";

@countries = ('US Commercial','US Organization','Network','US Government','US Military','US Educational','International','Afghanistan','Albania','Algeria','American Somoa','Andorra','Angola','Anguilla','Antarctica','Antigua and Barbuda','Argentina','Armenia','Aruba','Australia','Austria','Azerbaijan','Bahrain','Bangladesh','Barbados','Belarus','Belgium','Belize','Benin','Bermuda','Bhutan','Bolivia','Bosnia and Herzegovina','Botswana','Bouvet Island','Brazil','British Indian Ocean Territory','Brunei','Bulgaria','Burkina Faso','Burundi','Cambodia','Cameroon','Canada','Cape Verde','Central African Republic','Chad','Channel Islands - Guernsey','Channel Islands - Jersey','Chile','China','Christmas Island','Cocos (Keeling) Islands','Colombia','Comoros','Congo','Cook Islands','Costa Rica','Coted Ivoire','Croatia','Cuba','Cyprus','Czech Republic','Denmark','Djibouti','Dominica','Dominican Republic','East Timor','Ecuador','Egypt','El Salvador','Equatorial Guinea','Eritrea','Estonia','Ethiopia','Falklands Islands','Faroe Islands','Fiji','Finland','France','French Guiana','French Polynesia','French Southern Territories','French Metropolitan','Gabon','Georgia','Germany','Ghana','Gibraltar','Greece','Greenland','Grenada','Guadeloupe','Guam','Guatemala','Guinea','Guyana','Haiti','Heardand McDonald Islands','Honduras','HongKong','Hungary','Iceland','India','Indonesia','Iran','Iraq','Ireland','Israel','Italy','Jamaica','Japan','Jordan','Kazakhstan','Kenya','Kiribati','Peoples Republic of Democratic Korea','Republic of Korea','Kuwait','Kyrgyzstan','Laos','Latvia','Lebanon','Lesotho','Liberia','Libyan Arab Jamahiriya','Liechtenstein','Lithuania','Luxembourg','Macao','Macedonia','Malawi','Malaysia','Mali','Malta','Marshall Islands','Martinique','Mauritania','Mauritius','Mayotte','Mexico','Micronesia','Moldova','Monaco','Mongolia','Montserrat','Morocco','Mozambique','Myanmar','Namibia','Nauru','Nepal','Netherlands','Netherlands Antilles','New Caledonia','New Zealand','Nicaragua','Niger','Nigeria','Niue','Norfolk Island','Northern Mariana Islands','Norway','Oman','Pakistan','Palau','Panama','Papua New Guinea','Paraguay','Peru','Philippines','Pitcairn','Poland','Portugal','Puerto Rico','Qatar','Reunion','Romania','Russia','Rwanda','Saint Kitts and Nevis','Saint Lucia','Saint Vincent and the Grenadines','Samoa','San Marino','Sao Tomeand Principe','Saudi Arabia','Senegal','Seychelles','Sierra Leone','Singapore','Slovakia','Slovenia','Solomon Islands','Somalia','South Africa','South Georgia and the South Sandwich Islands','Spain','Sri Lanka','St. Helena','St. Pierreand Miquelon','Sudan','Suriname','Svalbardand Jan Mayen Islands','Swaziland','Sweden','Switzerland','Syria','Taiwan','Tajikistan','Tanzania','Thailand','The Bahamas','The Cayman Islands','Tonga','Trinidad and Tobago','Tunisia','Turkey','Turkmenistan','Turks and Caicos Islands','Tuvalu','Uganda','Ukraine','United Arab Emirates','United Kingdom','United States','United States Minor Outlying Islands','Urugauy','Uzbekistan','Vanuatu','Vatican City State','Venezuela','Vietnam','Virgin Islands (British)','Virgin Islands (US)','Wallis and Futuna Islands','Western Sahara','Yemen','Yugoslavia','Zaire','Zambia','Zimbabwe','Unknown Location');
@domainext = ('com','org','net','gov','mil','edu','int','af','al','dz','as','ad','ao','ai','aq','ag','ar','am','aw','au','at','az','bh','bd','bb','by','be','bz','bj','bm','bt','bo','ba','bw','bv','br','io','bn','bg','bf','bi','kh','cm','ca','cv','cf','td','gg','je','cl','cn','cx','cc','co','km','cg','ck','cr','ci','hr','cu','cy','cz','dk','dj','dm','do','tp','ec','eg','sv','gq','er','ee','et','fk','fo','fj','fi','fr','gf','pf','tf','fx','ga','ge','de','gh','gi','gr','gl','gd','gp','gu','gt','gn','gy','ht','hm','hn','hk','hu','is','in','id','ir','iq','ie','il','it','jm','jp','jo','kz','ke','ki','kp','kr','kw','kg','la','lv','lb','ls','lr','ly','li','lt','lu','mo','mk','mw','my','ml','mt','mh','mq','mr','mu','yt','mx','fm','md','mc','mn','ms','ma','mz','mm','na','nr','np','nl','an','nc','nz','ni','ne','ng','nu','nf','mp','no','om','pk','pw','pa','pq','py','pe','ph','pn','pl','pt','pr','qa','re','ro','ru','rw','kn','lc','vc','ws','sm','st','sa','sn','sc','sl','sg','sk','si','sb','so','za','gs','es','lk','sh','pm','sd','sr','sj','sz','se','ch','sy','tw','tj','tz','th','bs','ky','to','tt','tn','tr','tm','tc','tv','ug','ua','ae','uk','us','um','uy','uz','vu','va','ve','vn','vg','vi','wf','eh','ye','yu','zr','zm','zw','other');

# Get query string info
&get;

# Assign default values.
if (!($IN{'file'})){$IN{'file'} = "default"}
if (!($IN{'style'})){$IN{'style'} = "default"}
if (!($IN{'what'})){$IN{'what'} = "count"}

# So hackers don't change the dir...
$IN{'file'} =~ s/\.\.//g;
$IN{'file'} =~ s/\///g;

# Check for valid host.
if ($ENV{'HTTP_REFERER'})
{
   foreach $goodhost (@allowed)
   {
      if ($ENV{'HTTP_REFERER'} =~ /$goodhost/i){$good = 1; last;}
   }
   if ($good != 1)
   {
      open(ERROR, $error);
      print "Content-type: image/png\n\n";
      print <ERROR>;
      close(ERROR);
      exit(0);
   }
}


# Extract data from file.
open (DATA, "$data_dir$IN{'file'}");
$data = <DATA>;
close(DATA);
($hits,$htoday,$location,$v1,$v2,$v3,$v4,$v5,$v6,$v7,$v8,$v9,$v10,$v11,$v12,$v13,$v14,$v15,$v16,$v17,$v18,$v19,$v20,$r1,$r2,$r3,$r4,$r5,$r6,$r7,$r8,$r9,$r10,$r11,$r12,$r13,$r14,$r15,$r16,$r17,$r18,$r19,$r20,$browsers,$platforms) = split(/&&/, $data);
($today, $hitstoday) = split(/=/, $htoday);
($CEXT{'com'},$CEXT{'org'},$CEXT{'net'},$CEXT{'gov'},$CEXT{'mil'},$CEXT{'edu'},$CEXT{'int'},$CEXT{'af'},$CEXT{'al'},$CEXT{'dz'},$CEXT{'as'},$CEXT{'ad'},$CEXT{'ao'},$CEXT{'ai'},$CEXT{'aq'},$CEXT{'ag'},$CEXT{'ar'},$CEXT{'am'},$CEXT{'aw'},$CEXT{'au'},$CEXT{'at'},$CEXT{'az'},$CEXT{'bh'},$CEXT{'bd'},$CEXT{'bb'},$CEXT{'by'},$CEXT{'be'},$CEXT{'bz'},$CEXT{'bj'},$CEXT{'bm'},$CEXT{'bt'},$CEXT{'bo'},$CEXT{'ba'},$CEXT{'bw'},$CEXT{'bv'},$CEXT{'br'},$CEXT{'io'},$CEXT{'bn'},$CEXT{'bg'},$CEXT{'bf'},$CEXT{'bi'},$CEXT{'kh'},$CEXT{'cm'},$CEXT{'ca'},$CEXT{'cv'},$CEXT{'cf'},$CEXT{'td'},$CEXT{'gg'},$CEXT{'je'},$CEXT{'cl'},$CEXT{'cn'},$CEXT{'cx'},$CEXT{'cc'},$CEXT{'co'},$CEXT{'km'},$CEXT{'cg'},$CEXT{'ck'},$CEXT{'cr'},$CEXT{'ci'},$CEXT{'hr'},$CEXT{'cu'},$CEXT{'cy'},$CEXT{'cz'},$CEXT{'dk'},$CEXT{'dj'},$CEXT{'dm'},$CEXT{'do'},$CEXT{'tp'},$CEXT{'ec'},$CEXT{'eg'},$CEXT{'sv'},$CEXT{'gq'},$CEXT{'er'},$CEXT{'ee'},$CEXT{'et'},$CEXT{'fk'},$CEXT{'fo'},$CEXT{'fj'},$CEXT{'fi'},$CEXT{'fr'},$CEXT{'gf'},$CEXT{'pf'},$CEXT{'tf'},$CEXT{'fx'},$CEXT{'ga'},$CEXT{'ge'},$CEXT{'de'},$CEXT{'gh'},$CEXT{'gi'},$CEXT{'gr'},$CEXT{'gl'},$CEXT{'gd'},$CEXT{'gp'},$CEXT{'gu'},$CEXT{'gt'},$CEXT{'gn'},$CEXT{'gy'},$CEXT{'ht'},$CEXT{'hm'},$CEXT{'hn'},$CEXT{'hk'},$CEXT{'hu'},$CEXT{'is'},$CEXT{'in'},$CEXT{'id'},$CEXT{'ir'},$CEXT{'iq'},$CEXT{'ie'},$CEXT{'il'},$CEXT{'it'},$CEXT{'jm'},$CEXT{'jp'},$CEXT{'jo'},$CEXT{'kz'},$CEXT{'ke'},$CEXT{'ki'},$CEXT{'kp'},$CEXT{'kr'},$CEXT{'kw'},$CEXT{'kg'},$CEXT{'la'},$CEXT{'lv'},$CEXT{'lb'},$CEXT{'ls'},$CEXT{'lr'},$CEXT{'ly'},$CEXT{'li'},$CEXT{'lt'},$CEXT{'lu'},$CEXT{'mo'},$CEXT{'mk'},$CEXT{'mw'},$CEXT{'my'},$CEXT{'ml'},$CEXT{'mt'},$CEXT{'mh'},$CEXT{'mq'},$CEXT{'mr'},$CEXT{'mu'},$CEXT{'yt'},$CEXT{'mx'},$CEXT{'fm'},$CEXT{'md'},$CEXT{'mc'},$CEXT{'mn'},$CEXT{'ms'},$CEXT{'ma'},$CEXT{'mz'},$CEXT{'mm'},$CEXT{'na'},$CEXT{'nr'},$CEXT{'np'},$CEXT{'nl'},$CEXT{'an'},$CEXT{'nc'},$CEXT{'nz'},$CEXT{'ni'},$CEXT{'ne'},$CEXT{'ng'},$CEXT{'nu'},$CEXT{'nf'},$CEXT{'mp'},$CEXT{'no'},$CEXT{'om'},$CEXT{'pk'},$CEXT{'pw'},$CEXT{'pa'},$CEXT{'pq'},$CEXT{'py'},$CEXT{'pe'},$CEXT{'ph'},$CEXT{'pn'},$CEXT{'pl'},$CEXT{'pt'},$CEXT{'pr'},$CEXT{'qa'},$CEXT{'re'},$CEXT{'ro'},$CEXT{'ru'},$CEXT{'rw'},$CEXT{'kn'},$CEXT{'lc'},$CEXT{'vc'},$CEXT{'ws'},$CEXT{'sm'},$CEXT{'st'},$CEXT{'sa'},$CEXT{'sn'},$CEXT{'sc'},$CEXT{'sl'},$CEXT{'sg'},$CEXT{'sk'},$CEXT{'si'},$CEXT{'sb'},$CEXT{'so'},$CEXT{'za'},$CEXT{'gs'},$CEXT{'es'},$CEXT{'lk'},$CEXT{'sh'},$CEXT{'pm'},$CEXT{'sd'},$CEXT{'sr'},$CEXT{'sj'},$CEXT{'sz'},$CEXT{'se'},$CEXT{'ch'},$CEXT{'sy'},$CEXT{'tw'},$CEXT{'tj'},$CEXT{'tz'},$CEXT{'th'},$CEXT{'bs'},$CEXT{'ky'},$CEXT{'to'},$CEXT{'tt'},$CEXT{'tn'},$CEXT{'tr'},$CEXT{'tm'},$CEXT{'tc'},$CEXT{'tv'},$CEXT{'ug'},$CEXT{'ua'},$CEXT{'ae'},$CEXT{'uk'},$CEXT{'us'},$CEXT{'um'},$CEXT{'uy'},$CEXT{'uz'},$CEXT{'vu'},$CEXT{'va'},$CEXT{'ve'},$CEXT{'vn'},$CEXT{'vg'},$CEXT{'vi'},$CEXT{'wf'},$CEXT{'eh'},$CEXT{'ye'},$CEXT{'yu'},$CEXT{'zr'},$CEXT{'zm'},$CEXT{'zw'},$CEXT{'other'}) = split(/\|/, $location);
@browsers = split(/\|/, $browsers); @browsers = sort(@browsers);
@platforms = split(/\|/, $platforms); @platforms = sort(@platforms);

# See if user wants to view stats.
if ($IN{'what'} =~ /(view)\b/i){&stats}

# Check for counter reload.
($ldate, $ltime, $lhost, $laddr) = split(/\|/, $v1);
if ($ENV{'REMOTE_ADDR'} ne $laddr || $reloads == 0)
{
   # Find the location of the user.
   @subnet_numbers = split (/\./, $ENV{'REMOTE_ADDR'});
   $packed_address = pack ("C4", @subnet_numbers);
   $ENV{'REMOTE_HOST'} = gethostbyaddr($packed_address, 2);
   (@uaddr) = split(/\./, $ENV{'REMOTE_HOST'}); $myext = $uaddr[$#uaddr]; $myext =~ tr/A-Z/a-z/;
   if (!($ENV{'REMOTE_HOST'})){$ENV{'REMOTE_HOST'} = $ENV{'REMOTE_ADDR'}}
   if (defined $CEXT{$myext}) {$CEXT{$myext}++;}
   else {$CEXT{'other'}++;}
   if ($cdate ne $today){$hitstoday = 0; $today = $cdate;}

   # Find the user's browser
   if    ($ENV{'HTTP_USER_AGENT'} =~ m#aol (\d+)|iweng (\d+)|aolbrowser/(\d+)#oi){$browser = "AOL $1"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#msie (\d+)|msie/(\d+)|internet explorer/(\d+)#oi){$browser = "MSIE $1"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#webtv#oi){$browser = "WebTV"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#msie|microsoft#oi) {$browser = "MSIE"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#validator|rover|scooter|reaper|roamer|links|infoseek|harvest|check|crawl|gozilla|bot|frontpage|slurp|spider#oi){$browser = "Spider/Robot"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#opera#oi){if ($ENV{'HTTP_USER_AGENT'} =~ m#opera/(\d+)|opera (\d)#oi){$browser = "Opera $1"}else{$browser = "Opera"}}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#ncsa|mosaic#oi){$browser = "Mosaic"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#lynx#oi){$browser = "Lynx"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#mozilla/(\d+) (.*)#oi){$vmozilla = $1; $browser = "Netscape $vmozilla"}
   else  {$browser = "Unknown";}
   $i = 0;
   foreach $brsr (@browsers)
   {
      ($nbrsr, $hbrsr) = split(/=/, $brsr);
      if ($browser eq $nbrsr){$fbrsr = 1; $hbrsr++; $browsers[$i] = "$nbrsr=$hbrsr"; last;}
      $i++;
   }
   if ($fbrsr != 1){$#browsers++; $browsers[$#browsers] = "$browser=1"}
   $browsers = join('|', @browsers);

   # Find the users platform.
   if    ($browser eq "Spider/Robot"){$platform = "Spider/Robot"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#win#oi){if ($ENV{'HTTP_USER_AGENT'} =~ m#win95|windows 95|windows95|win 95#oi){$platform = "Windows 95"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#win98|windows98|windows 98|win 98#oi){$platform = "Windows 98"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#winnt|windowsnt|windows nt|win nt#oi){$platform = "Windows NT"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#windows 3.1|win3.1|win 3.1#oi){$platform = "Windows 3.1"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#windows#oi){$platform = "Windows"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#window#oi){$platform = "X Windows"}else {$platform = "Windows"}}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#mac#oi){if ($ENV{'HTTP_USER_AGENT'} =~ m#ppc|powerpc#oi){$platform = "Mac PowerPC"}elsif($ENV{'HTTP_USER_AGENT'} =~ m#imac#oi){$platform = "IMac"}else{$platform = "Mac"}}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#x11#oi){if ($ENV{'HTTP_USER_AGENT'} =~ m#hp-ux#oi){$platform = "UNIX (HP-UX)"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#linux#oi){$platform = "Linux"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#sunos#oi){$platform = "UNIX (SunOS)"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#bsd#oi){$longplatform = "UNIX (BSD)"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#aix#oi){$longplatform = "UNIX (AIX)"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#osf1#oi){$platform = "UNIX (OSF1)"}elsif ($ENV{'HTTP_USER_AGENT'} =~ m#irix#oi){$platform = "UNIX (IRIX)"}else {$platform = "UNIX"}}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#webtv#oi){$platform = "WebTV"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#iweng#oi){$platform = "Windows"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#lynx#oi){$platform = "UNIX"}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#os/2#oi){$platform = "OS/2";}
   elsif ($ENV{'HTTP_USER_AGENT'} =~ m#amiga#oi){$platform = "Amiga"}
   else  {$platform = "Unknown";}
   $i = 0;
   foreach $plfm (@platforms)
   {
      ($nplfm, $hplfm) = split(/=/, $plfm);
      if ($platform eq $nplfm){$fplfm = 1; $hplfm++; $platforms[$i] = "$nplfm=$hplfm"; last;}
      $i++;
   }
   if ($fplfm != 1){$#platforms++; $platforms[$#platforms] = "$platform=1"}
   $platforms = join('|', @platforms);

   # Add a hit
   $hits++; $hitstoday++;

   # Write to the file.
   open (DATA, ">$data_dir$IN{'file'}");
   flock(DATA, 2);
   seek(DATA, 0, 2);
   print DATA "$hits&&$today=$hitstoday&&$CEXT{'com'}|$CEXT{'org'}|$CEXT{'net'}|$CEXT{'gov'}|$CEXT{'mil'}|$CEXT{'edu'}|$CEXT{'int'}|$CEXT{'af'}|$CEXT{'al'}|$CEXT{'dz'}|$CEXT{'as'}|$CEXT{'ad'}|$CEXT{'ao'}|$CEXT{'ai'}|$CEXT{'aq'}|$CEXT{'ag'}|$CEXT{'ar'}|$CEXT{'am'}|$CEXT{'aw'}|$CEXT{'au'}|$CEXT{'at'}|$CEXT{'az'}|$CEXT{'bh'}|$CEXT{'bd'}|$CEXT{'bb'}|$CEXT{'by'}|$CEXT{'be'}|$CEXT{'bz'}|$CEXT{'bj'}|$CEXT{'bm'}|$CEXT{'bt'}|$CEXT{'bo'}|$CEXT{'ba'}|$CEXT{'bw'}|$CEXT{'bv'}|$CEXT{'br'}|$CEXT{'io'}|$CEXT{'bn'}|$CEXT{'bg'}|$CEXT{'bf'}|$CEXT{'bi'}|$CEXT{'kh'}|$CEXT{'cm'}|$CEXT{'ca'}|$CEXT{'cv'}|$CEXT{'cf'}|$CEXT{'td'}|$CEXT{'gg'}|$CEXT{'je'}|$CEXT{'cl'}|$CEXT{'cn'}|$CEXT{'cx'}|$CEXT{'cc'}|$CEXT{'co'}|$CEXT{'km'}|$CEXT{'cg'}|$CEXT{'ck'}|$CEXT{'cr'}|$CEXT{'ci'}|$CEXT{'hr'}|$CEXT{'cu'}|$CEXT{'cy'}|$CEXT{'cz'}|$CEXT{'dk'}|$CEXT{'dj'}|$CEXT{'dm'}|$CEXT{'do'}|$CEXT{'tp'}|$CEXT{'ec'}|$CEXT{'eg'}|$CEXT{'sv'}|$CEXT{'gq'}|$CEXT{'er'}|$CEXT{'ee'}|$CEXT{'et'}|$CEXT{'fk'}|$CEXT{'fo'}|$CEXT{'fj'}|$CEXT{'fi'}|$CEXT{'fr'}|$CEXT{'gf'}|$CEXT{'pf'}|$CEXT{'tf'}|$CEXT{'fx'}|$CEXT{'ga'}|$CEXT{'ge'}|$CEXT{'de'}|$CEXT{'gh'}|$CEXT{'gi'}|$CEXT{'gr'}|$CEXT{'gl'}|$CEXT{'gd'}|$CEXT{'gp'}|$CEXT{'gu'}|$CEXT{'gt'}|$CEXT{'gn'}|$CEXT{'gy'}|$CEXT{'ht'}|$CEXT{'hm'}|$CEXT{'hn'}|$CEXT{'hk'}|$CEXT{'hu'}|$CEXT{'is'}|$CEXT{'in'}|$CEXT{'id'}|$CEXT{'ir'}|$CEXT{'iq'}|$CEXT{'ie'}|$CEXT{'il'}|$CEXT{'it'}|$CEXT{'jm'}|$CEXT{'jp'}|$CEXT{'jo'}|$CEXT{'kz'}|$CEXT{'ke'}|$CEXT{'ki'}|$CEXT{'kp'}|$CEXT{'kr'}|$CEXT{'kw'}|$CEXT{'kg'}|$CEXT{'la'}|$CEXT{'lv'}|$CEXT{'lb'}|$CEXT{'ls'}|$CEXT{'lr'}|$CEXT{'ly'}|$CEXT{'li'}|$CEXT{'lt'}|$CEXT{'lu'}|$CEXT{'mo'}|$CEXT{'mk'}|$CEXT{'mw'}|$CEXT{'my'}|$CEXT{'ml'}|$CEXT{'mt'}|$CEXT{'mh'}|$CEXT{'mq'}|$CEXT{'mr'}|$CEXT{'mu'}|$CEXT{'yt'}|$CEXT{'mx'}|$CEXT{'fm'}|$CEXT{'md'}|$CEXT{'mc'}|$CEXT{'mn'}|$CEXT{'ms'}|$CEXT{'ma'}|$CEXT{'mz'}|$CEXT{'mm'}|$CEXT{'na'}|$CEXT{'nr'}|$CEXT{'np'}|$CEXT{'nl'}|$CEXT{'an'}|$CEXT{'nc'}|$CEXT{'nz'}|$CEXT{'ni'}|$CEXT{'ne'}|$CEXT{'ng'}|$CEXT{'nu'}|$CEXT{'nf'}|$CEXT{'mp'}|$CEXT{'no'}|$CEXT{'om'}|$CEXT{'pk'}|$CEXT{'pw'}|$CEXT{'pa'}|$CEXT{'pq'}|$CEXT{'py'}|$CEXT{'pe'}|$CEXT{'ph'}|$CEXT{'pn'}|$CEXT{'pl'}|$CEXT{'pt'}|$CEXT{'pr'}|$CEXT{'qa'}|$CEXT{'re'}|$CEXT{'ro'}|$CEXT{'ru'}|$CEXT{'rw'}|$CEXT{'kn'}|$CEXT{'lc'}|$CEXT{'vc'}|$CEXT{'ws'}|$CEXT{'sm'}|$CEXT{'st'}|$CEXT{'sa'}|$CEXT{'sn'}|$CEXT{'sc'}|$CEXT{'sl'}|$CEXT{'sg'}|$CEXT{'sk'}|$CEXT{'si'}|$CEXT{'sb'}|$CEXT{'so'}|$CEXT{'za'}|$CEXT{'gs'}|$CEXT{'es'}|$CEXT{'lk'}|$CEXT{'sh'}|$CEXT{'pm'}|$CEXT{'sd'}|$CEXT{'sr'}|$CEXT{'sj'}|$CEXT{'sz'}|$CEXT{'se'}|$CEXT{'ch'}|$CEXT{'sy'}|$CEXT{'tw'}|$CEXT{'tj'}|$CEXT{'tz'}|$CEXT{'th'}|$CEXT{'bs'}|$CEXT{'ky'}|$CEXT{'to'}|$CEXT{'tt'}|$CEXT{'tn'}|$CEXT{'tr'}|$CEXT{'tm'}|$CEXT{'tc'}|$CEXT{'tv'}|$CEXT{'ug'}|$CEXT{'ua'}|$CEXT{'ae'}|$CEXT{'uk'}|$CEXT{'us'}|$CEXT{'um'}|$CEXT{'uy'}|$CEXT{'uz'}|$CEXT{'vu'}|$CEXT{'va'}|$CEXT{'ve'}|$CEXT{'vn'}|$CEXT{'vg'}|$CEXT{'vi'}|$CEXT{'wf'}|$CEXT{'eh'}|$CEXT{'ye'}|$CEXT{'yu'}|$CEXT{'zr'}|$CEXT{'zm'}|$CEXT{'zw'}|$CEXT{'other'}&&$cdate|$ctime|$ENV{'REMOTE_HOST'}|$ENV{'REMOTE_ADDR'}&&$v1&&$v2&&$v3&&$v4&&$v5&&$v6&&$v7&&$v8&&$v9&&$v10&&$v11&&$v12&&$v13&&$v14&&$v15&&$v16&&$v17&&$v18&&$v19&&$r1&&$r2&&$r3&&$r4&&$r5&&$r6&&$r7&&$r8&&$r9&&$r10&&$r11&&$r12&&$r13&&$r14&&$r15&&$r16&&$r17&&$r18&&$r19&&$r20&&$browsers&&$platforms";
   close(DATA);
   flock(DATA, 8);
}

# Print the image and exit.
&doimage;
exit(0);

##################################################################
# Subroutine to print out an image.
sub doimage
{
   # Get the proper image dimensions.
   open(DIM, "$digits_dir$IN{'style'}/dim");
   ($x, $y) = split(/x/, <DIM>);
   close(DIM);

   # Create the png.
   $imx = (length($hits) * $x);
   $imy = $y;
   $image = new GD::Image($imx,$imy);

   # Assign color values.
   $white = $image->colorAllocate(255, 255, 255);

   # Create a transparent background.
   $image->transparent($white);
   $image->interlaced('true');

   $startx = 0; $endx = $x;
   foreach $digit (split(//, $hits))
   {
      $tile = newFromPng GD::Image("$digits_dir$IN{'style'}/$digit.png");

      $image->setTile($tile);
      $image->filledRectangle($startx,0,$endx,$y,gdTiled);

      $startx += $x;
      $endx += $x;
   }

   # Print MiMe type and the image.
   print "Content-type: image/png\n\n";
   print $image->png;
}

##################################################################
# Stats page.
sub stats
{
   # Add commas to the hits.
   $hits_tmp = $hits;
   $hitstoday_tmp = $hitstoday;
   while ($hits_tmp =~ s/(.*\d)(\d\d\d)/$1,$2/){}
   while ($hitstoday_tmp =~ s/(.*\d)(\d\d\d)/$1,$2/){}

   print "Content-type: text/html\n\n";
   print "<html>\n";
   print "<head><title>PAGE STATS FOR $IN{'file'}</title></head>\n";
   print "<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#0000FF\" vlink=\"#0000FF\" alink=\"#000000\">\n";
   print "<font face=\"Arial,Verdana\"><h2 align=\"center\">Page Stats For <font color=\"#BB0000\">$IN{'file'}</font></h2>\n";
   print "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"2\">\n";
   print "<tr><td bgcolor=\"#00AAFF\" colspan=\"2\"><b>Totals...</b></td></tr>\n";
   print "<tr bgcolor=\"#E0E0E0\"><td>Total Hits:</td><td align=\"right\">$hits_tmp</td></tr>\n";
   print "<tr bgcolor=\"#EEEEEE\"><td>Hits Today:</td><td align=\"right\">$hitstoday_tmp</td></tr>\n";
   print "<tr><td bgcolor=\"#00DD00\" colspan=\"2\"><b>Geographic Locations...</b></td></tr>\n";
   $c = 0;
   $color = 0;
   foreach $chits (split(/\|/, $location))
   {
      $cname = @countries[$c];
      $cext = @domainext[$c];
      if ($chits > 0)
      {
         $percent = (int(($chits/$hits)*10000)/100);
         $lwidth = int($percent*2);
         $lrwidth = ((200-$lwidth)+7);
         if ($color == 1)
         {
            print "<tr bgcolor=\"#EEEEEE\"><td><nobr>$cname ($cext):</nobr></td><td align=\"right\"><nobr><font size=\"2\">$percent% </font><img src=\"$pbar2\" border=\"0\" width=\"$lrwidth\" height=\"8\"><img src=\"$pcap\" border=\"0\" width=\"7\" height=\"8\"><img src=\"$pbar\" height=\"8\" width=\"$lwidth\" border=\"0\"></nobr></td></tr>\n";
            $color = 0;
         }
         else
         {
            print "<tr bgcolor=\"#E0E0E0\"><td><nobr>$cname ($cext):</nobr></td><td align=\"right\"><nobr><font size=\"2\">$percent% </font><img src=\"$pbar2\" border=\"0\" width=\"$lrwidth\" height=\"8\"><img src=\"$pcap\" border=\"0\" width=\"7\" height=\"8\"><img src=\"$pbar\" height=\"8\" width=\"$lwidth\" border=\"0\"></nobr></td></tr>\n";
            $color = 1;
         }
      }
      $c++;
   }
   print "<tr><td bgcolor=\"#EEDD00\" colspan=\"2\"><b>Browsers ...</b></td></tr>\n";
   $color = 0;
   foreach $browser (@browsers)
   {
      ($bname, $bhits) = split(/=/, $browser);
      $percent = (int(($bhits/$hits)*10000)/100);
      $bwidth = int($percent*2);
      $brwidth = ((200-$bwidth)+7);
      if ($color == 1)
      {
         print "<tr bgcolor=\"#EEEEEE\"><td><nobr>$bname:</nobr></td><td align=\"right\"><nobr><font size=\"2\">$percent% </font><img src=\"$pbar2\" border=\"0\" width=\"$brwidth\" height=\"8\"><img src=\"$pcap\" border=\"0\" height=\"8\" width=\"7\"><img src=\"$pbar\" height=\"8\" width=\"$bwidth\" border=\"0\"></nobr></td></tr>\n";
         $color = 0;
         next;
      }
      else
      {
         print "<tr bgcolor=\"#E0E0E0\"><td><nobr>$bname:</nobr></td><td align=\"right\"><nobr><font size=\"2\">$percent% </font><img src=\"$pbar2\" border=\"0\" width=\"$brwidth\" height=\"8\"><img src=\"$pcap\" border=\"0\" height=\"8\" width=\"7\"><img src=\"$pbar\" height=\"8\" width=\"$bwidth\" border=\"0\"></nobr></td></tr>\n";
         $color = 1;
      }
   }
   print "<tr><td bgcolor=\"#AA00EE\" colspan=\"2\"><b>Platforms ...</b></td></tr>\n";
   $color = 0;
   foreach $platform (@platforms)
   {
      ($pname, $phits) = split(/=/, $platform);
      $percent = (int(($phits/$hits)*10000)/100);
      $pwidth = int($percent*2);
      $prwidth = ((200-$pwidth)+7);
      if ($color == 1)
      {
         print "<tr bgcolor=\"#EEEEEE\"><td><nobr>$pname:</nobr></td><td align=\"right\"><nobr><font size=\"2\">$percent% </font><img src=\"$pbar2\" border=\"0\" width=\"$prwidth\" height=\"8\"><img src=\"$pcap\" border=\"0\" height=\"8\" width=\"7\"><img src=\"$pbar\" height=\"8\" width=\"$pwidth\" border=\"0\"></nobr></td></tr>\n";
         $color = 0;
         next;
      }
      else
      {
         print "<tr bgcolor=\"#E0E0E0\"><td><nobr>$pname:</nobr></td><td align=\"right\"><nobr><font size=\"2\">$percent% </font><img src=\"$pbar2\" border=\"0\" width=\"$prwidth\" height=\"8\"><img src=\"$pcap\" border=\"0\" height=\"8\" width=\"7\"><img src=\"$pbar\" height=\"8\" width=\"$pwidth\" border=\"0\"></nobr></td></tr>\n";
         $color = 1;
      }
   }
   print "<tr><td bgcolor=\"#DD0000\" colspan=\"2\"><b>Last 20 visitors...</b></td></tr>\n";
   $color = 0;
   foreach $visit ($v1,$v2,$v3,$v4,$v5,$v6,$v7,$v8,$v9,$v10,$v11,$v12,$v13,$v14,$v15,$v16,$v17,$v18,$v19,$v20)
   {
      if ($visit)
      {
         ($odate, $otime, $host, $addr) = split(/\|/, $visit);
         if ($color == 1)
         {
            print "<tr bgcolor=\"#EEEEEE\"><td>[$odate $otime]</td><td>$host ($addr)</td></tr>\n";
            $color = 0;
            next;
         }
         else
         {
            print "<tr bgcolor=\"#E0E0E0\"><td>[$odate $otime]</td><td>$host ($addr)</td></tr>\n";
            $color = 1;
         }
      }
   }
   print "</table><p align=\"center\"><font size=\"2\">Page stats created by the <a href=\"http://www.stanback.net\">BS Counter</a>. Copyright 2000 Brian Stanback.</font></p></font></body></html>\n";
   exit(0);
}

##################################################################
# Parse query info
sub get
{
   @pairs = split(/&/, $ENV{'QUERY_STRING'});
   foreach $pair (@pairs)
   {
      ($name, $value) = split(/=/, $pair);
      $value =~ tr/+/ /;
      $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
      $value =~ s/\n/<br>/g;
      $value =~ s/[;&\*'\|\.\/]//g;
      $IN{$name} = $value;
   }
}
