) {
$key =~ /^([^\t]+)\t+([^\t]+)/o;
$UrlMatch[$iter][0] = $1;
$UrlMatch[$iter][1] = $2;
$iter++;
}
close URLALIASFILE;
close URLMATCHFILE;
debug(" Plugin urlalias: UrlAlias file loaded: ".(scalar keys %UrlAlias)." entries found.");
debug(" Plugin urlalias: UrlMatch file loaded: ".(scalar @UrlMatch)." entries found.");
$urlinfoloaded=1;
}
if ($param) {
if ($UrlAlias{$param}) {
print "$UrlAlias{$param}
";
$found=1;
}
else {
foreach my $iter (0..@UrlMatch-1) {
my $key = $UrlMatch[$iter][0];
if ( $param =~ /$key/ ) {
print "$UrlMatch[$iter][1]
";
$found = 1;
# $UrlAlias{$param} = $UrlMatch[$iter][1];
# if ($SiteConfig && open(URLALIASFILE,">> $DirData/urlalias.$SiteConfig.txt")) {
# $filetoload="$DirData/urlalias.$SiteConfig.txt";
# }
# elsif (open(URLALIASFILE,">> $DirData/urlalias.txt")) {
# $filetoload="$DirData/urlalias.txt";
# }
# else {
# error("Couldn't open UrlAlias file \"$DirData/urlalias.txt\": $!");
# }
# print URLALIASFILE "$param\t$UrlAlias{$param}";
# close URLALIASFILE;
last;
}
}
}
if (!$found) { # does nothing right now
print "";
}
}
else { print ""; } # Url info title
return 1;
# ----->
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/geoip_asn_maxmind.pm 0000640 0001750 0001750 00000051414 12410217071 021422 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# GeoIp_ASN_Maxmind AWStats plugin
# This plugin allow you to add ASN information to a report
# Requires the free ASN database from MaxMind
#-----------------------------------------------------------------------------
# Perl Required Modules: Geo::IP or Geo::IP::PurePerl
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
use vars qw/ $type /;
$type='GeoIPASNum';
if (!eval ('require "Geo/IP.pm";')) {
$error1=$@;
$type='geoippureperl';
if (!eval ('require "Geo/IP/PurePerl.pm";')) {
$error2=$@;
$ret=($error1||$error2)?"Error:\n$error1$error2":"";
$ret.="Error: Need Perl module Geo::IP or Geo::IP::PurePerl";
return $ret;
}
}
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="6.2";
my $PluginHooksFunctions="AddHTMLMenuLink AddHTMLGraph ShowInfoHost
SectionInitHashArray SectionProcessIp SectionProcessHostname
SectionReadHistory SectionWriteHistory";
my $PluginName="geoip_asn_maxmind";
my $LoadedOverride=0;
my %TmpLookup;
my $LookupLink="";
my $OverrideFile="";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$geoip_asn_maxmind
%_asn_p
%_asn_h
%_asn_k
%_asn_l
$MAXNBOFSECTIONGIR
$MAXLENGTH
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
# Parameters: $mode - Whether to load into memory or search file for lookups
# Values: GEOIPSTANDARD () or GEOIP_MEMORY_CACHE
# $datafile - Path to the GEOIP Data file. Defaults to local directory
# $override - Path to an override file
# $link - ASN lookup link to a page with more information. Appends
# the AS number at the end. For example:
# $link=http://www.lookup.net/lookup.php?asn={ASNUMBER}
#-----------------------------------------------------------------------------
sub Init_geoip_asn_maxmind {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
$MAXNBOFSECTIONGIR=10;
$MAXLENGTH=20;
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin $PluginName: InitParams=$InitParams",1);
my ($mode,$tmpdatafile)=split(/\s+/,$InitParams,2);
my ($datafile,$override,$link)=split(/\+/,$tmpdatafile,3);
if (! $datafile) { $datafile="GeoIPASNum.dat"; }
else { $datafile =~ s/%20/ /g; }
if ($type eq 'geoippureperl') {
# With pureperl with always use GEOIP_STANDARD.
# GEOIP_MEMORY_CACHE seems to fail with ActiveState
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
else { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
} else {
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::GEOIP_MEMORY_CACHE(); }
else { $mode=Geo::IP::GEOIP_STANDARD(); }
}
# if there is a url in the override field, move it to link
if (lc($override) =~ m/^http/) { $link = $override; $override = ''; }
elsif ($override) { $override =~ s/%20/ /g; $OverrideFile=$override; }
if ($link){$LookupLink=$link;}
debug(" Plugin $PluginName: GeoIP initialized type=$type mode=$mode, override=$override, link=$link",1);
if ($type eq 'geoippureperl') {
$geoip_asn_maxmind = Geo::IP::PurePerl->open($datafile, $mode);
} else {
$geoip_asn_maxmind = Geo::IP->open($datafile, $mode);
}
# Fails on some GeoIP version
# debug(" Plugin geoip_org_maxmind: GeoIP initialized database_info=".$geoip_asn_maxmind->database_info());
if ($geoip_asn_maxmind) { debug(" Plugin $PluginName: GeoIP plugin and gi object initialized",1); }
else { return "Error: Failed to create gi object for datafile=".$datafile; }
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLMenuLink_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLMenuLink_geoip_asn_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
if ($Debug) { debug(" Plugin $PluginName: AddHTMLMenuLink"); }
if ($categ eq 'who') {
$menu->{"plugin_$PluginName"}=0.7; # Pos
$menulink->{"plugin_$PluginName"}=2; # Type of link
$menutext->{"plugin_$PluginName"}="ASNs"; # Text
}
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLGraph_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLGraph_geoip_asn_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
my $ShowISP='H';
$MinHit{'Org'}=1;
my $total_p; my $total_h; my $total_k;
my $rest_p; my $rest_h; my $rest_k;
if ($Debug) { debug(" Plugin $PluginName: AddHTMLGraph $categ $menu $menulink $menutext"); }
my $title='AS Numbers';
&tab_head("$title",19,0,'org');
print "AS Numbers: ".((scalar keys %_asn_h)-($_asn_h{'unknown'}?1:0))." | ";
print "ISP | \n";
if ($ShowISP =~ /P/i) { print "$Message[56] | "; }
if ($ShowISP =~ /P/i) { print "$Message[15] | "; }
if ($ShowISP =~ /H/i) { print "$Message[57] | "; }
if ($ShowISP =~ /H/i) { print "$Message[15] | "; }
if ($ShowISP =~ /B/i) { print "$Message[75] | "; }
if ($ShowISP =~ /L/i) { print "$Message[9] | "; }
print "
\n";
$total_p=$total_h=$total_k=0;
my $count=0;
&BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Org'},\%_asn_h,\%_asn_h);
foreach my $key (@keylist) {
if ($key eq 'unknown') { next; }
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int($_asn_p{$key}/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($_asn_h{$key}/$TotalHits*1000)/10; }
print "";
my $asn=$key; $asn =~ s/_/ /g;
my $idx = index($asn, ' ');
# get lookup link
my $link = '';
if ($LookupLink){
if ($idx < 0 && $asn =~ m/^A/){ $link .= $LookupLink.$asn; }
elsif (substr($asn, 0, $idx) =~ m/^A/){$link .= $LookupLink.substr($asn, 0, $idx); }
if ($link){ $link = "";}
}
print "".$link.ucfirst(($idx > -1 ? substr($asn, 0, $idx) : $asn));
print ($link ? "" : "")." | ";
print "".($idx > -1 ? substr($asn, $idx+1) : " ")." | \n";
if ($ShowISP =~ /P/i) { print "".($_asn_p{$key}?Format_Number($_asn_p{$key}):" ")." | "; }
if ($ShowISP =~ /P/i) { print "".($_asn_p{$key}?"$p_p %":' ')." | "; }
if ($ShowISP =~ /H/i) { print "".($_asn_h{$key}?Format_Number($_asn_h{$key}):" ")." | "; }
if ($ShowISP =~ /H/i) { print "".($_asn_h{$key}?"$p_h %":' ')." | "; }
if ($ShowISP =~ /B/i) { print "".Format_Bytes($_asn_k{$key})." | "; }
if ($ShowISP =~ /L/i) { print "".($_asn_p{$key}?Format_Date($_asn_l{$key},1):'-')." | "; }
print "
\n";
$total_p += $_asn_p{$key}||0;
$total_h += $_asn_h{$key};
$total_k += $_asn_k{$key}||0;
$count++;
}
if ($Debug) { debug("Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h",2); }
$rest_p=0;
$rest_h=$TotalHits-$total_h;
$rest_k=0;
if ($rest_p > 0 || $rest_h > 0 || $rest_k > 0) { # All other cities
# print "";
# print " | ";
# if ($ShowISP =~ /P/i) { print " | "; }
# if ($ShowISP =~ /P/i) { print " | "; }
# if ($ShowISP =~ /H/i) { print " | "; }
# if ($ShowISP =~ /H/i) { print " | "; }
# if ($ShowISP =~ /B/i) { print " | "; }
# if ($ShowISP =~ /L/i) { print " | "; }
# print "
\n";
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int($rest_p/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($rest_h/$TotalHits*1000)/10; }
print "";
print "$Message[2]/$Message[0] | ";
print " | \n";
if ($ShowISP =~ /P/i) { print "".($rest_p?Format_Number($rest_p):" ")." | "; }
if ($ShowISP =~ /P/i) { print "".($rest_p?"$p_p %":' ')." | "; }
if ($ShowISP =~ /H/i) { print "".($rest_h?Format_Number($rest_h):" ")." | "; }
if ($ShowISP =~ /H/i) { print "".($rest_h?"$p_h %":' ')." | "; }
if ($ShowISP =~ /B/i) { print "".Format_Bytes($rest_k)." | "; }
if ($ShowISP =~ /L/i) { print " | "; }
print "
\n";
}
&tab_end();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: ShowInfoHost_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to add additionnal columns to the Hosts report.
# This function is called when building rows of the report (One call for each
# row). So it allows you to add a column in report, for example with code :
# print "This is a new cell for $param | ";
# Parameters: Host name or ip
#-----------------------------------------------------------------------------
sub ShowInfoHost_geoip_asn_maxmind {
my $param="$_[0]";
# <-----
if ($param eq '__title__') {
my $NewLinkParams=${QueryString};
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)output(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
my $NewLinkTarget='';
if ($DetailedReportsOnNewWindows) { $NewLinkTarget=" target=\"awstatsbis\""; }
if (($FrameName eq 'mainleft' || $FrameName eq 'mainright') && $DetailedReportsOnNewWindows < 2) {
$NewLinkParams.="&framename=mainright";
$NewLinkTarget=" target=\"mainright\"";
}
$NewLinkParams =~ s/(&|&)+/&/i;
$NewLinkParams =~ s/^&//; $NewLinkParams =~ s/&$//;
if ($NewLinkParams) { $NewLinkParams="${NewLinkParams}&"; }
print "";
print "GeoIP ASN";
print " | ";
}
elsif ($param) {
my $ip=0;
my $key;
if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
$ip=4;
$key=$param;
}
elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address
$ip=6;
$key=$param;
}
print "";
my $asn = 0;
if ($key && $ip==4) {
$asn = TmpLookup_geoip_asn_maxmind($param);
if (!$asn && $type eq 'geoippureperl')
{
# Function org_by_addr does not exists in PurePerl but org_by_name do same
$asn=$geoip_asn_maxmind->org_by_name($param) if $geoip_asn_maxmind;
}
elsif (!$asn)
{
$asn=$geoip_asn_maxmind->org_by_addr($param) if $geoip_asn_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetASNByIp for $param: [$asn]",5); }
}
if ($key && $ip==6) {
debug(" Plugin $PluginName: IPv6 not supported by MaxMind Free DBs: $key",3);
}
if (! $key) {
$asn = TmpLookup_geoip_asn_maxmind($param);
if (!$asn && $type eq 'geoippureperl')
{
$asn=$geoip_asn_maxmind->org_by_name($param) if $geoip_asn_maxmind;
}
elsif (!$asn)
{
$asn=$geoip_asn_maxmind->org_by_name($param) if $geoip_asn_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetOrgByHostname for $param: [$asn]",5); }
}
if (length($asn)>0) {
my $link = '';
my $idx = index(trim($asn), ' ');
if ($LookupLink){
if ($idx < 0 && $asn =~ m/^A/){ $link .= $LookupLink.$asn; }
elsif (substr($asn, 0, $idx) =~ m/^A/){$link .= $LookupLink.substr($asn, 0, $idx); }
}
if ($link){ $link = "";}
if ($idx > -1 ) {$asn = substr(trim($asn), $idx+1);}
if (length($asn) <= $MAXLENGTH) {
print "$link$asn".($link ? "" : "");
}
else {
print $link.substr($asn,0,$MAXLENGTH).'...'.($link ? "" : "");
}
}
else { print "$Message[0]"; }
print " | ";
}
else {
print " | ";
}
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionInitHashArray_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionInitHashArray_geoip_asn_maxmind {
# my $param="$_[0]";
# <-----
if ($Debug) { debug(" Plugin $PluginName: Init_HashArray"); }
%_asn_p = %_asn_h = %_asn_k = %_asn_l =();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessIP_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessIp_geoip_asn_maxmind {
my $param="$_[0]"; # Param must be an IP
# <-----
my $asn = TmpLookup_geoip_asn_maxmind($param);
if (!$asn && $type eq 'geoippureperl')
{
# Function org_by_addr does not exists in PurePerl but org_by_name do same
$asn=$geoip_asn_maxmind->org_by_name($param) if $geoip_asn_maxmind;
}
elsif (!$asn)
{
$asn=$geoip_asn_maxmind->org_by_addr($param) if $geoip_asn_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetASNByIp for $param: [$asn]",5); }
if ($asn) {
$asn =~ s/\s/_/g;
$_asn_h{$asn}++;
} else {
$_asn_h{'unknown'}++;
}
# if ($timerecord > $_asn_l{$city}) { $_asn_l{$city}=$timerecord; }
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessHostname_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessHostname_geoip_asn_maxmind {
my $param="$_[0]"; # Param must be an IP
# <-----
my $asn = TmpLookup_geoip_asn_maxmind($param);
if (!$asn && $type eq 'geoippureperl')
{
$asn=$geoip_asn_maxmind->org_by_name($param) if $geoip_asn_maxmind;
}
elsif (!$asn)
{
$asn=$geoip_asn_maxmind->org_by_name($param) if $geoip_asn_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetOrgByHostname for $param: [$asn]",5); }
if ($asn) {
$asn =~ s/\s/_/g;
$_asn_h{$asn}++;
} else {
$_asn_h{'unknown'}++;
}
# if ($timerecord > $_asn_l{$city}) { $_asn_l{$city}=$timerecord; }
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionReadHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionReadHistory_geoip_asn_maxmind {
my $issectiontoload=shift;
my $xmlold=shift;
my $xmleb=shift;
my $countlines=shift;
# <-----
if ($Debug) { debug(" Plugin $PluginName: Begin of PLUGIN_geoip_org_maxmind section"); }
my @field=();
my $count=0;my $countloaded=0;
do {
if ($field[0]) {
$count++;
if ($issectiontoload) {
$countloaded++;
if ($field[2]) { $_asn_h{$field[0]}+=$field[2]; }
}
}
$_=;
chomp $_; s/\r//;
@field=split(/\s+/,($xmlold?XMLDecodeFromHisto($_):$_));
$countlines++;
}
until ($field[0] eq "END_PLUGIN_$PluginName" || $field[0] eq "${xmleb}END_PLUGIN_$PluginName" || ! $_);
if ($field[0] ne "END_PLUGIN_$PluginName" && $field[0] ne "${xmleb}END_PLUGIN_$PluginName") { error("History file is corrupted (End of section PLUGIN not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).","","",1); }
if ($Debug) { debug(" Plugin $PluginName: End of PLUGIN_geoip_org_maxmind section ($count entries, $countloaded loaded)"); }
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionWriteHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionWriteHistory_geoip_asn_maxmind {
my ($xml,$xmlbb,$xmlbs,$xmlbe,$xmlrb,$xmlrs,$xmlre,$xmleb,$xmlee)=(shift,shift,shift,shift,shift,shift,shift,shift,shift);
if ($Debug) { debug(" Plugin $PluginName: SectionWriteHistory_$PluginName start - ".(scalar keys %_asn_h)); }
# <-----
print HISTORYTMP "\n";
if ($xml) { print HISTORYTMP "$MAXNBOFSECTIONGIR\n"; }
print HISTORYTMP "# Plugin key - Pages - Hits - Bandwidth - Last access\n";
#print HISTORYTMP "# The $MaxNbOfExtra[$extranum] first number of hits are first\n";
$ValueInFile{'plugin_$PluginName'}=tell HISTORYTMP;
print HISTORYTMP "${xmlbb}BEGIN_PLUGIN_$PluginName${xmlbs}".(scalar keys %_asn_h)."${xmlbe}\n";
&BuildKeyList($MAXNBOFSECTIONGIR,1,\%_asn_h,\%_asn_h);
my %keysinkeylist=();
foreach (@keylist) {
$keysinkeylist{$_}=1;
#my $page=$_asn_p{$_}||0;
#my $bytes=$_asn_k{$_}||0;
#my $lastaccess=$_asn_l{$_}||'';
print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_asn_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
foreach (keys %_asn_h) {
if ($keysinkeylist{$_}) { next; }
#my $page=$_asn_p{$_}||0;
#my $bytes=$_asn_k{$_}||0;
#my $lastaccess=$_asn_l{$_}||'';
print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_asn_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
print HISTORYTMP "${xmleb}END_PLUGIN_$PluginName${xmlee}\n";
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: LoadOverrideFile
# Attempts to load a comma delimited file that will override the GeoIP database
# Useful for Intranet records
# CSV format: IP,2-char Country code
#-----------------------------------------------------------------------------
sub LoadOverrideFile_geoip_asn_maxmind{
my $filetoload="";
if ($OverrideFile){
if (!open(GEOIPFILE, $OverrideFile)){
debug("Plugin $PluginName: Unable to open override file: $OverrideFile");
$LoadedOverride = 1;
return;
}
}else{
my $conf = (exists(&Get_Config_Name) ? Get_Config_Name() : $SiteConfig);
if ($conf && open(GEOIPFILE,"$DirData/$PluginName.$conf.txt")) { $filetoload="$DirData/$PluginName.$conf.txt"; }
elsif (open(GEOIPFILE,"$DirData/$PluginName.txt")) { $filetoload="$DirData/$PluginName.txt"; }
else { debug("No override file \"$DirData/$PluginName.txt\": $!"); }
}
if ($filetoload)
{
# This is the fastest way to load with regexp that I know
while (){
chomp $_;
s/\r//;
my @record = split(",", $_);
# replace quotes if they were used in the file
foreach (@record){ $_ =~ s/"//g; }
# store in hash
$TmpLookup{$record[0]} = $record[1];
}
close GEOIPFILE;
debug(" Plugin $PluginName: Overload file loaded: ".(scalar keys %TmpLookup)." entries found.");
}
$LoadedOverride = 1;
return;
}
sub trim($)
{
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: TmpLookup
# Searches the temporary hash for the parameter value and returns the corresponding
# GEOIP entry
#-----------------------------------------------------------------------------
sub TmpLookup_geoip_asn_maxmind(){
$param = shift;
if (!$LoadedOverride){&LoadOverrideFile_geoip_asn_maxmind();}
# my $val;
# if ($geoip_asn_maxmind &&
# (($type eq 'geoip' && $geoip_asn_maxmind->VERSION >= 1.30) ||
# $type eq 'geoippureperl' && $geoip_asn_maxmind->VERSION >= 1.17)){
# $val = $TmpLookup{$geoip_asn_maxmind->get_ip_address($param)};
# }
# else {$val = $TmpLookup{$param};}
# return $val || '';
return $TmpLookup{$param}||'';
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/geoip.pm 0000640 0001750 0001750 00000023207 12410217071 017043 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# GeoIp Maxmind AWStats plugin
# This plugin allow you to get country report with countries detected
# from a Geographical database (GeoIP internal database) instead of domain
# hostname suffix.
# Need the country database from Maxmind (free).
#-----------------------------------------------------------------------------
# Perl Required Modules: Geo::IP or Geo::IP::PurePerl
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
use vars qw/ $type /;
$type='geoip';
if (!eval ('require "Geo/IP.pm";')) {
$error1=$@;
$type='geoippureperl';
if (!eval ('require "Geo/IP/PurePerl.pm";')) {
$error2=$@;
$ret=($error1||$error2)?"Error:\n$error1$error2":"";
$ret.="Error: Need Perl module Geo::IP or Geo::IP::PurePerl";
return $ret;
}
}
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="5.4";
my $PluginHooksFunctions="GetCountryCodeByAddr GetCountryCodeByName ShowInfoHost";
my $PluginName = "geoip";
my $LoadedOverride=0;
my $OverrideFile="";
my %TmpDomainLookup;
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$gi
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_geoip {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin $PluginName: InitParams=$InitParams",1);
my ($mode,$tmpdatafile)=split(/\s+/,$InitParams,2);
my ($datafile,$override)=split(/\+/,$tmpdatafile,2);
if (! $datafile) { $datafile="$PluginName.dat"; }
else { $datafile =~ s/%20/ /g; }
if ($type eq 'geoippureperl') {
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::PurePerl::GEOIP_MEMORY_CACHE(); }
else { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
} else {
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::GEOIP_MEMORY_CACHE(); }
else { $mode=Geo::IP::GEOIP_STANDARD(); }
}
if ($override){$OverrideFile=$override;}
%TmpDomainLookup=();
debug(" Plugin $PluginName: GeoIP try to initialize type=$type mode=$mode override=$override datafile=$datafile",1);
if ($type eq 'geoippureperl') {
$gi = Geo::IP::PurePerl->open($datafile, $mode);
} else {
$gi = Geo::IP->open($datafile, $mode);
}
# Fails on some GeoIP version
# debug(" Plugin $PluginName: GeoIP initialized database_info=".$gi->database_info());
if ($gi) { debug(" Plugin $PluginName: GeoIP plugin and gi object initialized",1); }
else { return "Error: Failed to create gi object for datafile=".$datafile; }
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetCountryCodeByAddr_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# GetCountryCodeByAddr is called to translate an ip into a country code in lower case.
#-----------------------------------------------------------------------------
sub GetCountryCodeByAddr_geoip {
my $param="$_[0]";
# <-----
if (! $param) { return ''; }
my $res= TmpLookup_geoip($param);
if (! $res) {
$res=lc($gi->country_code_by_addr($param)) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: Already resolved to [$res]",5); }
# ----->
return $res;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetCountryCodeByName_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# GetCountryCodeByName is called to translate a host name into a country code in lower case.
#-----------------------------------------------------------------------------
sub GetCountryCodeByName_geoip {
my $param="$_[0]";
# <-----
if (! $param) { return ''; }
my $res = TmpLookup_geoip($param);
if (! $res) {
$res=lc($gi->country_code_by_name($param)) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: Already resolved to [$res]",5); }
# ----->
return $res;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: ShowInfoHost_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to add additionnal columns to the Hosts report.
# This function is called when building rows of the report (One call for each
# row). So it allows you to add a column in report, for example with code :
# print "This is a new cell for $param | ";
# Parameters: Host name or ip
#-----------------------------------------------------------------------------
sub ShowInfoHost_geoip {
my $param="$_[0]";
# <-----
if ($param eq '__title__') {
my $NewLinkParams=${QueryString};
$NewLinkParams =~ s/(^|&)update(=\w*|$)//i;
$NewLinkParams =~ s/(^|&)output(=\w*|$)//i;
$NewLinkParams =~ s/(^|&)staticlinks(=\w*|$)//i;
$NewLinkParams =~ s/(^|&)framename=[^&]*//i;
my $NewLinkTarget='';
if ($DetailedReportsOnNewWindows) { $NewLinkTarget=" target=\"awstatsbis\""; }
if (($FrameName eq 'mainleft' || $FrameName eq 'mainright') && $DetailedReportsOnNewWindows < 2) {
$NewLinkParams.="&framename=mainright";
$NewLinkTarget=" target=\"mainright\"";
}
$NewLinkParams =~ tr/&/&/s; $NewLinkParams =~ s/^&//; $NewLinkParams =~ s/&$//;
if ($NewLinkParams) { $NewLinkParams="${NewLinkParams}&"; }
print "";
print "GeoIP Country";
print " | ";
}
elsif ($param) {
my $ip=0;
my $key;
if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
$ip=4;
$key=$param;
}
elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address
$ip=6;
$key=$param;
}
print "";
if ($key && $ip==4) {
my $res = TmpLookup_geoip($param);
if (!$res){$res=lc($gi->country_code_by_addr($param)) if $gi;}
if ($Debug) { debug(" Plugin $PluginName: GetCountryByIp for $param: [$res]",5); }
if ($res) { print $DomainsHashIDLib{$res}?$DomainsHashIDLib{$res}:"$Message[0]"; }
else { print "$Message[0]"; }
}
if ($key && $ip==6) {
print "$Message[0]";
}
if (! $key) {
my $res = TmpLookup_geoip($param);
if (!$res){$res=lc($gi->country_code_by_name($param)) if $gi;}
if ($Debug) { debug(" Plugin $PluginName: GetCountryByHostname for $param: [$res]",5); }
if ($res) { print $DomainsHashIDLib{$res}?$DomainsHashIDLib{$res}:"$Message[0]"; }
else { print "$Message[0]"; }
}
print " | ";
}
else {
print " | ";
}
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: LoadOverrideFile
# Attempts to load a comma delimited file that will override the GeoIP database
# Useful for Intranet records
# CSV format: IP,2-char Country code
#-----------------------------------------------------------------------------
sub LoadOverrideFile_geoip{
my $filetoload="";
if ($OverrideFile){
if (!open(GEOIPFILE, $OverrideFile)){
debug("Plugin $PluginName: Unable to open override file: $OverrideFile");
$LoadedOverride = 1;
return;
}
}else{
my $conf = (exists(&Get_Config_Name) ? Get_Config_Name() : $SiteConfig);
if ($conf && open(GEOIPFILE,"$DirData/$PluginName.$conf.txt")) { $filetoload="$DirData/$PluginName.$conf.txt"; }
elsif (open(GEOIPFILE,"$DirData/$PluginName.txt")) { $filetoload="$DirData/$PluginName.txt"; }
else { debug("No override file \"$DirData/$PluginName.txt\": $!"); }
}
if ($filetoload)
{
# This is the fastest way to load with regexp that I know
while (){
chomp $_;
s/\r//;
my @record = split(",", $_);
# replace quotes if they were used in the file
foreach (@record){ $_ =~ s/"//g; }
# store in hash
$TmpDomainLookup{$record[0]} = $record[1];
}
close GEOIPFILE;
debug(" Plugin $PluginName: Overload file loaded: ".(scalar keys %TmpDomainLookup)." entries found.");
}
$LoadedOverride = 1;
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: TmpLookup
# Searches the temporary hash for the parameter value and returns the corresponding
# GEOIP entry
#-----------------------------------------------------------------------------
sub TmpLookup_geoip(){
$param = shift;
if (!$LoadedOverride){&LoadOverrideFile_geoip();}
#my $val;
#if ($gi &&
#(($type eq 'geoip' && $gi->VERSION >= 1.30) ||
# $type eq 'geoippureperl' && $gi->VERSION >= 1.17)){
# $val = $TmpDomainLookup{$gi->get_ip_address($param)};
#}
#else {$val = $TmpDomainLookup{$param};}
#return $val || '';
return $TmpDomainLookup{$param}||'';
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/tooltips.pm 0000640 0001750 0001750 00000017675 12410217071 017631 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# Tooltips AWStats plugin
# This plugin allow you to add some toolpus in AWStats HTML report pages.
# The tooltip are in same language than the report (they are stored in the
# awstats-tt-codelanguage.txt files in lang directory).
#-----------------------------------------------------------------------------
# Perl Required Modules: None
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES.
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="6.1";
my $PluginHooksFunctions="AddHTMLStyles AddHTMLBodyHeader";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$TOOLTIPWIDTH
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_tooltips {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin tooltips: InitParams=$InitParams",1);
$TOOLTIPON=1;
$TOOLTIPWIDTH=380; # Width of tooltips
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLStyles_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to Add HTML styles at beginning of BODY section.
#-----------------------------------------------------------------------------
sub AddHTMLStyles_tooltips {
# <-----
print "div { font: 12px 'Arial','Verdana','Helvetica', sans-serif; text-align: justify; }\n";
print ".CTooltip { position:absolute; top: 0px; left: 0px; z-index: 2; width: ${TOOLTIPWIDTH}px; visibility:hidden; font: 8pt 'MS Comic Sans','Arial',sans-serif; background-color: #FFFFE6; padding: 8px; border: 1px solid black; }\n";
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNTION: AddHTMLBodyHeader_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to Add HTML code at beginning of BODY section.
#-----------------------------------------------------------------------------
sub AddHTMLBodyHeader_tooltips {
# <-----
if ($FrameName ne 'mainleft') {
# GET AND WRITE THE TOOLTIP STRINGS
#---------------------------------------------------------------------
&_ReadAndOutputTooltipFile($Lang);
# WRITE TOOLTIPS JAVASCRIPT CODE
#---------------------------------------------------------------------
# Position .style.pixelLeft/.pixelHeight/.pixelWidth/.pixelTop IE OK Opera OK
# .style.left/.height/.width/.top IE456 OK Netscape67 OK XHTML OK
# document.getElementById IE456 OK Opera OK Netscape67 OK XHTML OK
# document.body.offsetWidth|document.body.style.pixelWidth IE OK Opera OK Netscape OK XHTML KO Visible width of container
# document.documentElement.offsetWidth XHTML OK Visible width of container
# tooltipOBJ.offsetWidth|tooltipOBJ.style.pixelWidth IE OK Opera OK Netscape OK Width of an object
# event.clientXY IE OK Opera OK Netscape KO XHTML KO Position of mouse
# window.innerHeight IE OK Netscape OK Height of container
# window.pageYOffset ?
# document.body.scrollTop IE OK Opera OK Netscape OK XHTML KO Vertical position of scrollbar
my $docwidth="document.body.offsetWidth";
my $doctop="document.body.scrollTop";
if ($BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml') {
$docwidth="document.documentElement.offsetWidth";
$doctop="document.documentElement.scrollTop";
}
print <
function ShowTip(fArg)
{
var tooltipOBJ = (document.getElementById) ? document.getElementById('tt' + fArg) : eval("document.all['tt" + fArg + "']");
if (tooltipOBJ != null) {
var tooltipLft = ($docwidth?$docwidth:document.body.style.pixelWidth) - (tooltipOBJ.offsetWidth?tooltipOBJ.offsetWidth:(tooltipOBJ.style.pixelWidth?tooltipOBJ.style.pixelWidth:$TOOLTIPWIDTH)) - 30;
var tooltipTop = 10;
if (navigator.appName == 'Netscape') {
tooltipTop = ($doctop>=0?$doctop+10:event.clientY+10);
tooltipOBJ.style.top = tooltipTop+"px";
tooltipOBJ.style.left = tooltipLft+"px";
}
else {
tooltipTop = ($doctop>=0?$doctop+10:event.clientY+10);
tooltipTop = (document.body.scrollTop>=0?document.body.scrollTop+10:event.clientY+10);
EOF
# Seul IE en HTML a besoin de code suppl�mentaire. IE en xhtml est OK
if ($BuildReportFormat ne 'xhtml' && $BuildReportFormat ne 'xml') {
print < tooltipLft) && (event.clientY < (tooltipOBJ.scrollHeight?tooltipOBJ.scrollHeight:tooltipOBJ.style.pixelHeight) + 10)) {
tooltipTop = ($doctop?$doctop:document.body.offsetTop) + event.clientY + 20;
}
EOF
}
print <
EOF
}
return 1;
# ----->
}
#------------------------------------------------------------------------------
# Function: Get the tooltip texts for a specified language and write it
# Parameters: LanguageId
# Input: $DirLang $DIR
# Output: Full tooltips text
# Return: None
#------------------------------------------------------------------------------
sub _ReadAndOutputTooltipFile {
# Check lang files in common possible directories :
# Windows and standard package: "$DIR/lang" (lang in same dir than awstats.pl)
# Debian package : "/usr/share/awstats/lang"
# Other possible directories : "./lang"
my @PossibleLangDir=("$DirLang","${DIR}/lang","/usr/share/awstats/lang","./lang");
my $FileLang='';
my $logtype=lc($LogType ne 'S'?$LogType:'W');
foreach my $dir (@PossibleLangDir) {
my $searchdir=$dir;
if ($searchdir && (!($searchdir =~ /\/$/)) && (!($searchdir =~ /\\$/)) ) { $searchdir .= "/"; }
if (open(LANG,"${searchdir}tooltips_${logtype}/awstats-tt-$_[0].txt")) { $FileLang="${searchdir}tooltips_${logtype}/awstats-tt-$_[0].txt"; last; }
}
# If file not found, we try english
if (! $FileLang) {
foreach my $dir (@PossibleLangDir) {
my $searchdir=$dir;
if ($searchdir && (!($searchdir =~ /\/$/)) && (!($searchdir =~ /\\$/)) ) { $searchdir .= "/"; }
if (open(LANG,"${searchdir}tooltips_${logtype}/awstats-tt-en.txt")) { $FileLang="${searchdir}tooltips_${logtype}/awstats-tt-en.txt"; last; }
}
}
if ($Debug) { debug(" Plugin tooltips: Call to Read_Language_Tooltip [FileLang=\"$FileLang\"]"); }
if ($FileLang) {
my $aws_PROG=ucfirst($PROG);
my $aws_VisitTimeout = $VISITTIMEOUT/10000*60;
my $aws_NbOfRobots = scalar keys %RobotsHashIDLib;
my $aws_NbOfWorms = scalar @WormsSearchIDOrder;
my $aws_NbOfSearchEngines = scalar keys %SearchEnginesHashLib;
while () {
if ($_ =~ /\
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="6.5";
my $PluginHooksFunctions="AddHTMLMenuLink AddHTMLGraph ShowInfoHost SectionInitHashArray SectionProcessIp SectionProcessHostname SectionReadHistory SectionWriteHistory";
my $PluginName="geoip_city_maxmind";
my $LoadedOverride=0;
my $OverrideFile="";
my %TmpDomainLookup = {};
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$geoip_city_maxmind
%_city_p
%_city_h
%_city_k
%_city_l
$MAXNBOFSECTIONGIR
/;
my %countrylib=('ca'=>'Canadian Regions','us'=>'US regions');
my %regca=(
'AB',"Alberta",
'BC',"British Columbia",
'MB',"Manitoba",
'NB',"New Brunswick",
'NF',"Newfoundland",
'NS',"Nova Scotia",
'NU',"Nunavut",
'ON',"Ontario",
'PE',"Prince Edward Island",
'QC',"Quebec",
'SK',"Saskatchewan",
'NT',"Northwest Territories",
'YT',"Yukon Territory"
);
my %regus=(
'AA',"Armed Forces Americas",
'AE',"Armed Forces Europe, Middle East, & Canada",
'AK',"Alaska",
'AL',"Alabama",
'AP',"Armed Forces Pacific",
'AR',"Arkansas",
'AS',"American Samoa",
'AZ',"Arizona",
'CA',"California",
'CO',"Colorado",
'CT',"Connecticut",
'DC',"District of Columbia",
'DE',"Delaware",
'FL',"Florida",
'FM',"Federated States of Micronesia",
'GA',"Georgia",
'GU',"Guam",
'HI',"Hawaii",
'IA',"Iowa",
'ID',"Idaho",
'IL',"Illinois",
'IN',"Indiana",
'KS',"Kansas",
'KY',"Kentucky",
'LA',"Louisiana",
'MA',"Massachusetts",
'MD',"Maryland",
'ME',"Maine",
'MH',"Marshall Islands",
'MI',"Michigan",
'MN',"Minnesota",
'MO',"Missouri",
'MP',"Northern Mariana Islands",
'MS',"Mississippi",
'MT',"Montana",
'NC',"North Carolina",
'ND',"North Dakota",
'NE',"Nebraska",
'NH',"New Hampshire",
'NJ',"New Jersey",
'NM',"New Mexico",
'NV',"Nevada",
'NY',"New York",
'OH',"Ohio",
'OK',"Oklahoma",
'OR',"Oregon",
'PA',"Pennsylvania",
'PR',"Puerto Rico",
'PW',"Palau",
'RI',"Rhode Island",
'SC',"South Carolina",
'SD',"South Dakota",
'TN',"Tennessee",
'TX',"Texas",
'UT',"Utah",
'VA',"Virginia",
'VI',"Virgin Islands",
'VT',"Vermont",
'WA',"Washington",
'WV',"West Virginia",
'WI',"Wisconsin",
'WY',"Wyoming"
);
my %region=(
'ca'=>\%regca,
'us'=>\%regus
);
# "iso 3166 country code"_"fips 10-4 region code","region name"
my %regall=(
"AD_02","Canillo",
"AD_03","Encamp",
"AD_04","La Massana",
"AD_05","Ordino",
"AD_06","Sant Julia de Loria",
"AD_07","Andorra la Vella",
"AD_08","Escaldes-Engordany",
"AE_01","Abu Zaby",
"AE_03","Dubay",
"AE_04","Al Fujayrah",
"AE_05","Ra's al Khaymah",
"AE_06","Ash Shariqah",
"AE_07","Umm al Qaywayn",
"AF_01","Badakhshan",
"AF_02","Badghis",
"AF_03","Baghlan",
"AF_05","Bamian",
"AF_06","Farah",
"AF_07","Faryab",
"AF_08","Ghazni",
"AF_09","Ghowr",
"AF_10","Helmand",
"AF_11","Herat",
"AF_13","Kabol",
"AF_14","Kapisa",
"AF_15","Konar",
"AF_16","Laghman",
"AF_17","Lowgar",
"AF_18","Nangarhar",
"AF_19","Nimruz",
"AF_20","Oruzgan",
"AF_21","Paktia",
"AF_22","Parvan",
"AF_23","Kandahar",
"AF_24","Kondoz",
"AF_26","Takhar",
"AF_27","Vardak",
"AF_28","Zabol",
"AF_29","Paktika",
"AF_30","Balkh",
"AF_31","Jowzjan",
"AF_32","Samangan",
"AF_33","Sar-e Pol",
"AF_34","Konar",
"AF_35","Laghman",
"AF_36","Paktia",
"AF_37","Khowst",
"AF_38","Nurestan",
"AG_01","Barbuda",
"AG_03","Saint George",
"AG_04","Saint John",
"AG_05","Saint Mary",
"AG_06","Saint Paul",
"AG_07","Saint Peter",
"AG_08","Saint Philip",
"AL_40","Berat",
"AL_41","Diber",
"AL_42","Durres",
"AL_43","Elbasan",
"AL_44","Fier",
"AL_45","Gjirokaster",
"AL_46","Korce",
"AL_47","Kukes",
"AL_48","Lezhe",
"AL_49","Shkoder",
"AL_50","Tirane",
"AL_51","Vlore",
"AM_01","Aragatsotn",
"AM_02","Ararat",
"AM_03","Armavir",
"AM_04","Geghark'unik'",
"AM_05","Kotayk'",
"AM_06","Lorri",
"AM_07","Shirak",
"AM_08","Syunik'",
"AM_09","Tavush",
"AM_10","Vayots' Dzor",
"AM_11","Yerevan",
"AO_01","Benguela",
"AO_02","Bie",
"AO_03","Cabinda",
"AO_04","Cuando Cubango",
"AO_05","Cuanza Norte",
"AO_06","Cuanza Sul",
"AO_07","Cunene",
"AO_08","Huambo",
"AO_09","Huila",
"AO_12","Malanje",
"AO_14","Moxico",
"AO_15","Uige",
"AO_16","Zaire",
"AO_17","Lunda Norte",
"AO_18","Lunda Sul",
"AO_19","Bengo",
"AO_20","Luanda",
"AR_01","Buenos Aires",
"AR_02","Catamarca",
"AR_03","Chaco",
"AR_04","Chubut",
"AR_05","Cordoba",
"AR_06","Corrientes",
"AR_07","Distrito Federal",
"AR_08","Entre Rios",
"AR_09","Formosa",
"AR_10","Jujuy",
"AR_11","La Pampa",
"AR_12","La Rioja",
"AR_13","Mendoza",
"AR_14","Misiones",
"AR_15","Neuquen",
"AR_16","Rio Negro",
"AR_17","Salta",
"AR_18","San Juan",
"AR_19","San Luis",
"AR_20","Santa Cruz",
"AR_21","Santa Fe",
"AR_22","Santiago del Estero",
"AR_23","Tierra del Fuego",
"AR_24","Tucuman",
"AT_01","Burgenland",
"AT_02","Karnten",
"AT_03","Niederosterreich",
"AT_04","Oberosterreich",
"AT_05","Salzburg",
"AT_06","Steiermark",
"AT_07","Tirol",
"AT_08","Vorarlberg",
"AT_09","Wien",
"AU_01","Australian Capital Territory",
"AU_02","New South Wales",
"AU_03","Northern Territory",
"AU_04","Queensland",
"AU_05","South Australia",
"AU_06","Tasmania",
"AU_07","Victoria",
"AU_08","Western Australia",
"AZ_01","Abseron",
"AZ_02","Agcabadi",
"AZ_03","Agdam",
"AZ_04","Agdas",
"AZ_05","Agstafa",
"AZ_06","Agsu",
"AZ_07","Ali Bayramli",
"AZ_08","Astara",
"AZ_09","Baki",
"AZ_10","Balakan",
"AZ_11","Barda",
"AZ_12","Beylaqan",
"AZ_13","Bilasuvar",
"AZ_14","Cabrayil",
"AZ_15","Calilabad",
"AZ_16","Daskasan",
"AZ_17","Davaci",
"AZ_18","Fuzuli",
"AZ_19","Gadabay",
"AZ_20","Ganca",
"AZ_21","Goranboy",
"AZ_22","Goycay",
"AZ_23","Haciqabul",
"AZ_24","Imisli",
"AZ_25","Ismayilli",
"AZ_26","Kalbacar",
"AZ_27","Kurdamir",
"AZ_28","Lacin",
"AZ_29","Lankaran",
"AZ_30","Lankaran",
"AZ_31","Lerik",
"AZ_32","Masalli",
"AZ_33","Mingacevir",
"AZ_34","Naftalan",
"AZ_35","Naxcivan",
"AZ_36","Neftcala",
"AZ_37","Oguz",
"AZ_38","Qabala",
"AZ_39","Qax",
"AZ_40","Qazax",
"AZ_41","Qobustan",
"AZ_42","Quba",
"AZ_43","Qubadli",
"AZ_44","Qusar",
"AZ_45","Saatli",
"AZ_46","Sabirabad",
"AZ_47","Saki",
"AZ_48","Saki",
"AZ_49","Salyan",
"AZ_50","Samaxi",
"AZ_51","Samkir",
"AZ_52","Samux",
"AZ_53","Siyazan",
"AZ_54","Sumqayit",
"AZ_55","Susa",
"AZ_56","Susa",
"AZ_57","Tartar",
"AZ_58","Tovuz",
"AZ_59","Ucar",
"AZ_60","Xacmaz",
"AZ_61","Xankandi",
"AZ_62","Xanlar",
"AZ_63","Xizi",
"AZ_64","Xocali",
"AZ_65","Xocavand",
"AZ_66","Yardimli",
"AZ_67","Yevlax",
"AZ_68","Yevlax",
"AZ_69","Zangilan",
"AZ_70","Zaqatala",
"AZ_71","Zardab",
"BA_01","Federation of Bosnia and Herzegovina",
"BA_02","Republika Srpska",
"BB_01","Christ Church",
"BB_02","Saint Andrew",
"BB_03","Saint George",
"BB_04","Saint James",
"BB_05","Saint John",
"BB_06","Saint Joseph",
"BB_07","Saint Lucy",
"BB_08","Saint Michael",
"BB_09","Saint Peter",
"BB_10","Saint Philip",
"BB_11","Saint Thomas",
"BD_01","Barisal",
"BD_04","Bandarban",
"BD_05","Comilla",
"BD_12","Mymensingh",
"BD_13","Noakhali",
"BD_15","Patuakhali",
"BD_22","Bagerhat",
"BD_23","Bhola",
"BD_24","Bogra",
"BD_25","Barguna",
"BD_26","Brahmanbaria",
"BD_27","Chandpur",
"BD_28","Chapai Nawabganj",
"BD_29","Chattagram",
"BD_30","Chuadanga",
"BD_31","Cox's Bazar",
"BD_32","Dhaka",
"BD_33","Dinajpur",
"BD_34","Faridpur",
"BD_35","Feni",
"BD_36","Gaibandha",
"BD_37","Gazipur",
"BD_38","Gopalganj",
"BD_39","Habiganj",
"BD_40","Jaipurhat",
"BD_41","Jamalpur",
"BD_42","Jessore",
"BD_43","Jhalakati",
"BD_44","Jhenaidah",
"BD_45","Khagrachari",
"BD_46","Khulna",
"BD_47","Kishorganj",
"BD_48","Kurigram",
"BD_49","Kushtia",
"BD_50","Laksmipur",
"BD_51","Lalmonirhat",
"BD_52","Madaripur",
"BD_53","Magura",
"BD_54","Manikganj",
"BD_55","Meherpur",
"BD_56","Moulavibazar",
"BD_57","Munshiganj",
"BD_58","Naogaon",
"BD_59","Narail",
"BD_60","Narayanganj",
"BD_61","Narsingdi",
"BD_62","Nator",
"BD_63","Netrakona",
"BD_64","Nilphamari",
"BD_65","Pabna",
"BD_66","Panchagar",
"BD_67","Parbattya Chattagram",
"BD_68","Pirojpur",
"BD_69","Rajbari",
"BD_70","Rajshahi",
"BD_71","Rangpur",
"BD_72","Satkhira",
"BD_73","Shariyatpur",
"BD_74","Sherpur",
"BD_75","Sirajganj",
"BD_76","Sunamganj",
"BD_77","Sylhet",
"BD_78","Tangail",
"BD_79","Thakurgaon",
"BE_01","Antwerpen",
"BE_02","Brabant",
"BE_03","Hainaut",
"BE_04","Liege",
"BE_05","Limburg",
"BE_06","Luxembourg",
"BE_07","Namur",
"BE_08","Oost-Vlaanderen",
"BE_09","West-Vlaanderen",
"BE_10","Brabant Wallon",
"BE_11","Brussels Hoofdstedelijk Gewest",
"BE_12","Vlaams-Brabant",
"BF_15","Bam",
"BF_19","Boulkiemde",
"BF_20","Ganzourgou",
"BF_21","Gnagna",
"BF_28","Kouritenga",
"BF_33","Oudalan",
"BF_34","Passore",
"BF_36","Sanguie",
"BF_40","Soum",
"BF_42","Tapoa",
"BF_44","Zoundweogo",
"BF_45","Bale",
"BF_46","Banwa",
"BF_47","Bazega",
"BF_48","Bougouriba",
"BF_49","Boulgou",
"BF_50","Gourma",
"BF_51","Houet",
"BF_52","Ioba",
"BF_53","Kadiogo",
"BF_54","Kenedougou",
"BF_55","Komoe",
"BF_56","Komondjari",
"BF_57","Kompienga",
"BF_58","Kossi",
"BF_59","Koulpelogo",
"BF_60","Kourweogo",
"BF_61","Leraba",
"BF_62","Loroum",
"BF_63","Mouhoun",
"BF_64","Namentenga",
"BF_65","Naouri",
"BF_66","Nayala",
"BF_67","Noumbiel",
"BF_68","Oubritenga",
"BF_69","Poni",
"BF_70","Sanmatenga",
"BF_71","Seno",
"BF_72","Sissili",
"BF_73","Sourou",
"BF_74","Tuy",
"BF_75","Yagha",
"BF_76","Yatenga",
"BF_77","Ziro",
"BF_78","Zondoma",
"BG_33","Mikhaylovgrad",
"BG_38","Blagoevgrad",
"BG_39","Burgas",
"BG_40","Dobrich",
"BG_41","Gabrovo",
"BG_42","Grad Sofiya",
"BG_43","Khaskovo",
"BG_44","Kurdzhali",
"BG_45","Kyustendil",
"BG_46","Lovech",
"BG_47","Montana",
"BG_48","Pazardzhik",
"BG_49","Pernik",
"BG_50","Pleven",
"BG_51","Plovdiv",
"BG_52","Razgrad",
"BG_53","Ruse",
"BG_54","Shumen",
"BG_55","Silistra",
"BG_56","Sliven",
"BG_57","Smolyan",
"BG_58","Sofiya",
"BG_59","Stara Zagora",
"BG_60","Turgovishte",
"BG_61","Varna",
"BG_62","Veliko Turnovo",
"BG_63","Vidin",
"BG_64","Vratsa",
"BG_65","Yambol",
"BH_01","Al Hadd",
"BH_02","Al Manamah",
"BH_03","Al Muharraq",
"BH_05","Jidd Hafs",
"BH_06","Sitrah",
"BH_08","Al Mintaqah al Gharbiyah",
"BH_09","Mintaqat Juzur Hawar",
"BH_10","Al Mintaqah ash Shamaliyah",
"BH_11","Al Mintaqah al Wusta",
"BH_12","Madinat",
"BH_13","Ar Rifa",
"BH_14","Madinat Hamad",
"BI_02","Bujumbura",
"BI_09","Bubanza",
"BI_10","Bururi",
"BI_11","Cankuzo",
"BI_12","Cibitoke",
"BI_13","Gitega",
"BI_14","Karuzi",
"BI_15","Kayanza",
"BI_16","Kirundo",
"BI_17","Makamba",
"BI_18","Muyinga",
"BI_19","Ngozi",
"BI_20","Rutana",
"BI_21","Ruyigi",
"BI_22","Muramvya",
"BI_23","Mwaro",
"BJ_01","Atakora",
"BJ_02","Atlantique",
"BJ_03","Borgou",
"BJ_04","Mono",
"BJ_05","Oueme",
"BJ_06","Zou",
"BM_01","Devonshire",
"BM_02","Hamilton",
"BM_03","Hamilton",
"BM_04","Paget",
"BM_05","Pembroke",
"BM_06","Saint George",
"BM_07","Saint George's",
"BM_08","Sandys",
"BM_09","Smiths",
"BM_10","Southampton",
"BM_11","Warwick",
"BN_07","Alibori",
"BN_08","Belait",
"BN_09","Brunei and Muara",
"BN_10","Temburong",
"BN_11","Collines",
"BN_12","Kouffo",
"BN_13","Donga",
"BN_14","Littoral",
"BN_15","Tutong",
"BN_16","Oueme",
"BN_17","Plateau",
"BN_18","Zou",
"BO_01","Chuquisaca",
"BO_02","Cochabamba",
"BO_03","El Beni",
"BO_04","La Paz",
"BO_05","Oruro",
"BO_06","Pando",
"BO_07","Potosi",
"BO_08","Santa Cruz",
"BO_09","Tarija",
"BR_01","Acre",
"BR_02","Alagoas",
"BR_03","Amapa",
"BR_04","Amazonas",
"BR_05","Bahia",
"BR_06","Ceara",
"BR_07","Distrito Federal",
"BR_08","Espirito Santo",
"BR_11","Mato Grosso do Sul",
"BR_13","Maranhao",
"BR_14","Mato Grosso",
"BR_15","Minas Gerais",
"BR_16","Para",
"BR_17","Paraiba",
"BR_18","Parana",
"BR_20","Piaui",
"BR_21","Rio de Janeiro",
"BR_22","Rio Grande do Norte",
"BR_23","Rio Grande do Sul",
"BR_24","Rondonia",
"BR_25","Roraima",
"BR_26","Santa Catarina",
"BR_27","Sao Paulo",
"BR_28","Sergipe",
"BR_29","Goias",
"BR_30","Pernambuco",
"BR_31","Tocantins",
"BS_05","Bimini",
"BS_06","Cat Island",
"BS_10","Exuma",
"BS_13","Inagua",
"BS_15","Long Island",
"BS_16","Mayaguana",
"BS_18","Ragged Island",
"BS_22","Harbour Island",
"BS_23","New Providence",
"BS_24","Acklins and Crooked Islands",
"BS_25","Freeport",
"BS_26","Fresh Creek",
"BS_27","Governor's Harbour",
"BS_28","Green Turtle Cay",
"BS_29","High Rock",
"BS_30","Kemps Bay",
"BS_31","Marsh Harbour",
"BS_32","Nichollstown and Berry Islands",
"BS_33","Rock Sound",
"BS_34","Sandy Point",
"BS_35","San Salvador and Rum Cay",
"BT_05","Bumthang",
"BT_06","Chhukha",
"BT_07","Chirang",
"BT_08","Daga",
"BT_09","Geylegphug",
"BT_10","Ha",
"BT_11","Lhuntshi",
"BT_12","Mongar",
"BT_13","Paro",
"BT_14","Pemagatsel",
"BT_15","Punakha",
"BT_16","Samchi",
"BT_17","Samdrup",
"BT_18","Shemgang",
"BT_19","Tashigang",
"BT_20","Thimphu",
"BT_21","Tongsa",
"BT_22","Wangdi Phodrang",
"BW_01","Central",
"BW_02","Chobe",
"BW_03","Ghanzi",
"BW_04","Kgalagadi",
"BW_05","Kgatleng",
"BW_06","Kweneng",
"BW_07","Ngamiland",
"BW_08","North-East",
"BW_09","South-East",
"BW_10","Southern",
"BY_01","Brestskaya Voblasts'",
"BY_02","Homyel'skaya Voblasts'",
"BY_03","Hrodzyenskaya Voblasts'",
"BY_04","Minsk",
"BY_05","Minskaya Voblasts'",
"BY_06","Mahilyowskaya Voblasts'",
"BY_07","Vitsyebskaya Voblasts'",
"BZ_01","Belize",
"BZ_02","Cayo",
"BZ_03","Corozal",
"BZ_04","Orange Walk",
"BZ_05","Stann Creek",
"BZ_06","Toledo",
"CA_01","Alberta",
"CA_02","British Columbia",
"CA_03","Manitoba",
"CA_04","New Brunswick",
"CA_05","Newfoundland and Labrador",
"CA_07","Nova Scotia",
"CA_08","Ontario",
"CA_09","Prince Edward Island",
"CA_10","Quebec",
"CA_11","Saskatchewan",
"CA_12","Yukon Territory",
"CA_13","Northwest Territories",
"CA_14","Nunavut",
"CF_01","Bamingui-Bangoran",
"CF_02","Basse-Kotto",
"CF_03","Haute-Kotto",
"CF_04","Mambere-Kadei",
"CF_05","Haut-Mbomou",
"CF_06","Kemo",
"CF_07","Lobaye",
"CF_08","Mbomou",
"CF_09","Nana-Mambere",
"CF_11","Ouaka",
"CF_12","Ouham",
"CF_13","Ouham-Pende",
"CF_14","Vakaga",
"CF_15","Nana-Grebizi",
"CF_16","Sangha-Mbaere",
"CF_17","Ombella-Mpoko",
"CF_18","Bangui",
"CG_01","Bouenza",
"CG_03","Cuvette",
"CG_04","Kouilou",
"CG_05","Lekoumou",
"CG_06","Likouala",
"CG_07","Niari",
"CG_08","Plateaux",
"CG_10","Sangha",
"CG_11","Pool",
"CG_12","Brazzaville",
"CH_01","Aargau",
"CH_02","Ausser-Rhoden",
"CH_03","Basel-Landschaft",
"CH_04","Basel-Stadt",
"CH_05","Bern",
"CH_06","Fribourg",
"CH_07","Geneve",
"CH_08","Glarus",
"CH_09","Graubunden",
"CH_10","Inner-Rhoden",
"CH_11","Luzern",
"CH_12","Neuchatel",
"CH_13","Nidwalden",
"CH_14","Obwalden",
"CH_15","Sankt Gallen",
"CH_16","Schaffhausen",
"CH_17","Schwyz",
"CH_18","Solothurn",
"CH_19","Thurgau",
"CH_20","Ticino",
"CH_21","Uri",
"CH_22","Valais",
"CH_23","Vaud",
"CH_24","Zug",
"CH_25","Zurich",
"CH_26","Jura",
"CI_01","Abengourou",
"CI_03","Dabakala",
"CI_05","Adzope",
"CI_06","Agboville",
"CI_07","Biankouma",
"CI_11","Bouna",
"CI_12","Boundiali",
"CI_14","Danane",
"CI_16","Divo",
"CI_17","Ferkessedougou",
"CI_18","Gagnoa",
"CI_20","Katiola",
"CI_21","Korhogo",
"CI_23","Odienne",
"CI_25","Seguela",
"CI_26","Touba",
"CI_27","Bongouanou",
"CI_28","Issia",
"CI_29","Lakota",
"CI_30","Mankono",
"CI_31","Oume",
"CI_32","Soubre",
"CI_33","Tingrela",
"CI_34","Zuenoula",
"CI_36","Bangolo",
"CI_37","Beoumi",
"CI_38","Bondoukou",
"CI_39","Bouafle",
"CI_40","Bouake",
"CI_41","Daloa",
"CI_42","Daoukro",
"CI_44","Duekoue",
"CI_45","Grand-Lahou",
"CI_47","Man",
"CI_48","Mbahiakro",
"CI_49","Sakassou",
"CI_50","San Pedro",
"CI_51","Sassandra",
"CI_52","Sinfra",
"CI_53","Tabou",
"CI_54","Tanda",
"CI_55","Tiassale",
"CI_56","Toumodi",
"CI_57","Vavoua",
"CI_61","Abidjan",
"CI_62","Aboisso",
"CI_63","Adiake",
"CI_64","Alepe",
"CI_65","Bocanda",
"CI_66","Dabou",
"CI_67","Dimbokro",
"CI_68","Grand-Bassam",
"CI_69","Guiglo",
"CI_70","Jacqueville",
"CI_71","Tiebissou",
"CI_72","Toulepleu",
"CI_73","Yamoussoukro",
"CL_01","Valparaiso",
"CL_02","Aisen del General Carlos Ibanez del Campo",
"CL_03","Antofagasta",
"CL_04","Araucania",
"CL_05","Atacama",
"CL_06","Bio-Bio",
"CL_07","Coquimbo",
"CL_08","Libertador General Bernardo O'Higgins",
"CL_09","Los Lagos",
"CL_10","Magallanes y de la Antartica Chilena",
"CL_11","Maule",
"CL_12","Region Metropolitana",
"CL_13","Tarapaca",
"CM_04","Est",
"CM_05","Littoral",
"CM_07","Nord-Ouest",
"CM_08","Ouest",
"CM_09","Sud-Ouest",
"CM_10","Adamaoua",
"CM_11","Centre",
"CM_12","Extreme-Nord",
"CM_13","Nord",
"CM_14","Sud",
"CN_01","Anhui",
"CN_02","Zhejiang",
"CN_03","Jiangxi",
"CN_04","Jiangsu",
"CN_05","Jilin",
"CN_06","Qinghai",
"CN_07","Fujian",
"CN_08","Heilongjiang",
"CN_09","Henan",
"CN_10","Hebei",
"CN_11","Hunan",
"CN_12","Hubei",
"CN_13","Xinjiang",
"CN_14","Xizang",
"CN_15","Gansu",
"CN_16","Guangxi",
"CN_18","Guizhou",
"CN_19","Liaoning",
"CN_20","Nei Mongol",
"CN_21","Ningxia",
"CN_22","Beijing",
"CN_23","Shanghai",
"CN_24","Shanxi",
"CN_25","Shandong",
"CN_26","Shaanxi",
"CN_27","Sichuan",
"CN_28","Tianjin",
"CN_29","Yunnan",
"CN_30","Guangdong",
"CN_31","Hainan",
"CN_32","Chongqing",
"CO_01","Amazonas",
"CO_02","Antioquia",
"CO_03","Arauca",
"CO_04","Atlantico",
"CO_08","Caqueta",
"CO_09","Cauca",
"CO_10","Cesar",
"CO_11","Choco",
"CO_12","Cordoba",
"CO_14","Guaviare",
"CO_15","Guainia",
"CO_16","Huila",
"CO_17","La Guajira",
"CO_19","Meta",
"CO_20","Narino",
"CO_21","Norte de Santander",
"CO_22","Putumayo",
"CO_23","Quindio",
"CO_24","Risaralda",
"CO_25","San Andres y Providencia",
"CO_26","Santander",
"CO_27","Sucre",
"CO_28","Tolima",
"CO_29","Valle del Cauca",
"CO_30","Vaupes",
"CO_31","Vichada",
"CO_32","Casanare",
"CO_33","Cundinamarca",
"CO_34","Distrito Especial",
"CO_35","Bolivar",
"CO_36","Boyaca",
"CO_37","Caldas",
"CO_38","Magdalena",
"CR_01","Alajuela",
"CR_02","Cartago",
"CR_03","Guanacaste",
"CR_04","Heredia",
"CR_06","Limon",
"CR_07","Puntarenas",
"CR_08","San Jose",
"CU_01","Pinar del Rio",
"CU_02","Ciudad de la Habana",
"CU_03","Matanzas",
"CU_04","Isla de la Juventud",
"CU_05","Camaguey",
"CU_07","Ciego de Avila",
"CU_08","Cienfuegos",
"CU_09","Granma",
"CU_10","Guantanamo",
"CU_11","La Habana",
"CU_12","Holguin",
"CU_13","Las Tunas",
"CU_14","Sancti Spiritus",
"CU_15","Santiago de Cuba",
"CU_16","Villa Clara",
"CV_01","Boa Vista",
"CV_02","Brava",
"CV_04","Maio",
"CV_05","Paul",
"CV_07","Ribeira Grande",
"CV_08","Sal",
"CV_10","Sao Nicolau",
"CV_11","Sao Vicente",
"CV_13","Mosteiros",
"CV_14","Praia",
"CV_15","Santa Catarina",
"CV_16","Santa Cruz",
"CV_17","Sao Domingos",
"CV_18","Sao Filipe",
"CV_19","Sao Miguel",
"CV_20","Tarrafal",
"CY_01","Famagusta",
"CY_02","Kyrenia",
"CY_03","Larnaca",
"CY_04","Nicosia",
"CY_05","Limassol",
"CY_06","Paphos",
"CZ_52","Hlavni Mesto Praha",
"CZ_78","Jihomoravsky Kraj",
"CZ_79","Jihocesky Kraj",
"CZ_80","Vysocina",
"CZ_81","Karlovarsky Kraj",
"CZ_82","Kralovehradecky Kraj",
"CZ_83","Liberecky Kraj",
"CZ_84","Olomoucky Kraj",
"CZ_85","Moravskoslezsky Kraj",
"CZ_86","Pardubicky Kraj",
"CZ_87","Plzensky Kraj",
"CZ_88","Stredocesky Kraj",
"CZ_89","Ustecky Kraj",
"CZ_90","Zlinsky Kraj",
"DE_01","Baden-Wurttemberg",
"DE_02","Bayern",
"DE_03","Bremen",
"DE_04","Hamburg",
"DE_05","Hessen",
"DE_06","Niedersachsen",
"DE_07","Nordrhein-Westfalen",
"DE_08","Rheinland-Pfalz",
"DE_09","Saarland",
"DE_10","Schleswig-Holstein",
"DE_11","Brandenburg",
"DE_12","Mecklenburg-Vorpommern",
"DE_13","Sachsen",
"DE_14","Sachsen-Anhalt",
"DE_15","Thuringen",
"DE_16","Berlin",
"DJ_02","Dikhil",
"DJ_03","Djibouti",
"DJ_04","Obock",
"DJ_05","Tadjoura",
"DK_01","Arhus",
"DK_02","Bornholm",
"DK_03","Frederiksborg",
"DK_04","Fyn",
"DK_05","Kobenhavn",
"DK_06","Staden Kobenhavn",
"DK_07","Nordjylland",
"DK_08","Ribe",
"DK_09","Ringkobing",
"DK_10","Roskilde",
"DK_11","Sonderjylland",
"DK_12","Storstrom",
"DK_13","Vejle",
"DK_14","Vestsjalland",
"DK_15","Viborg",
"DM_02","Saint Andrew",
"DM_03","Saint David",
"DM_04","Saint George",
"DM_05","Saint John",
"DM_06","Saint Joseph",
"DM_07","Saint Luke",
"DM_08","Saint Mark",
"DM_09","Saint Patrick",
"DM_10","Saint Paul",
"DM_11","Saint Peter",
"DO_01","Azua",
"DO_02","Baoruco",
"DO_03","Barahona",
"DO_04","Dajabon",
"DO_05","Distrito Nacional",
"DO_06","Duarte",
"DO_08","Espaillat",
"DO_09","Independencia",
"DO_10","La Altagracia",
"DO_11","Elias Pina",
"DO_12","La Romana",
"DO_14","Maria Trinidad Sanchez",
"DO_15","Monte Cristi",
"DO_16","Pedernales",
"DO_17","Peravia",
"DO_18","Puerto Plata",
"DO_19","Salcedo",
"DO_20","Samana",
"DO_21","Sanchez Ramirez",
"DO_23","San Juan",
"DO_24","San Pedro De Macoris",
"DO_25","Santiago",
"DO_26","Santiago Rodriguez",
"DO_27","Valverde",
"DO_28","El Seibo",
"DO_29","Hato Mayor",
"DO_30","La Vega",
"DO_31","Monsenor Nouel",
"DO_32","Monte Plata",
"DO_33","San Cristobal",
"DZ_01","Alger",
"DZ_03","Batna",
"DZ_04","Constantine",
"DZ_06","Medea",
"DZ_07","Mostaganem",
"DZ_09","Oran",
"DZ_10","Saida",
"DZ_12","Setif",
"DZ_13","Tiaret",
"DZ_14","Tizi Ouzou",
"DZ_15","Tlemcen",
"DZ_18","Bejaia",
"DZ_19","Biskra",
"DZ_20","Blida",
"DZ_21","Bouira",
"DZ_22","Djelfa",
"DZ_23","Guelma",
"DZ_24","Jijel",
"DZ_25","Laghouat",
"DZ_26","Mascara",
"DZ_27","M'sila",
"DZ_29","Oum el Bouaghi",
"DZ_30","Sidi Bel Abbes",
"DZ_31","Skikda",
"DZ_33","Tebessa",
"DZ_34","Adrar",
"DZ_35","Ain Defla",
"DZ_36","Ain Temouchent",
"DZ_37","Annaba",
"DZ_38","Bechar",
"DZ_39","Bordj Bou Arreridj",
"DZ_40","Boumerdes",
"DZ_41","Chlef",
"DZ_42","El Bayadh",
"DZ_43","El Oued",
"DZ_44","El Tarf",
"DZ_45","Ghardaia",
"DZ_46","Illizi",
"DZ_47","Khenchela",
"DZ_48","Mila",
"DZ_49","Naama",
"DZ_50","Ouargla",
"DZ_51","Relizane",
"DZ_52","Souk Ahras",
"DZ_53","Tamanghasset",
"DZ_54","Tindouf",
"DZ_55","Tipaza",
"DZ_56","Tissemsilt",
"EC_01","Galapagos",
"EC_02","Azuay",
"EC_03","Bolivar",
"EC_04","Canar",
"EC_05","Carchi",
"EC_06","Chimborazo",
"EC_07","Cotopaxi",
"EC_08","El Oro",
"EC_09","Esmeraldas",
"EC_10","Guayas",
"EC_11","Imbabura",
"EC_12","Loja",
"EC_13","Los Rios",
"EC_14","Manabi",
"EC_15","Morona-Santiago",
"EC_17","Pastaza",
"EC_18","Pichincha",
"EC_19","Tungurahua",
"EC_20","Zamora-Chinchipe",
"EC_22","Sucumbios",
"EC_23","Napo",
"EC_24","Orellana",
"EE_01","Harjumaa",
"EE_02","Hiiumaa",
"EE_03","Ida-Virumaa",
"EE_04","Jarvamaa",
"EE_05","Jogevamaa",
"EE_06","Kohtla-Jarve",
"EE_07","Laanemaa",
"EE_08","Laane-Virumaa",
"EE_09","Narva",
"EE_10","Parnu",
"EE_11","Parnumaa",
"EE_12","Polvamaa",
"EE_13","Raplamaa",
"EE_14","Saaremaa",
"EE_15","Sillamae",
"EE_16","Tallinn",
"EE_17","Tartu",
"EE_18","Tartumaa",
"EE_19","Valgamaa",
"EE_20","Viljandimaa",
"EE_21","Vorumaa",
"EG_01","Ad Daqahliyah",
"EG_02","Al Bahr al Ahmar",
"EG_03","Al Buhayrah",
"EG_04","Al Fayyum",
"EG_05","Al Gharbiyah",
"EG_06","Al Iskandariyah",
"EG_07","Al Isma'iliyah",
"EG_08","Al Jizah",
"EG_09","Al Minufiyah",
"EG_10","Al Minya",
"EG_11","Al Qahirah",
"EG_12","Al Qalyubiyah",
"EG_13","Al Wadi al Jadid",
"EG_14","Ash Sharqiyah",
"EG_15","As Suways",
"EG_16","Aswan",
"EG_17","Asyut",
"EG_18","Bani Suwayf",
"EG_19","Bur Sa'id",
"EG_20","Dumyat",
"EG_21","Kafr ash Shaykh",
"EG_22","Matruh",
"EG_23","Qina",
"EG_24","Suhaj",
"EG_26","Janub Sina'",
"EG_27","Shamal Sina'",
"ES_07","Islas Baleares",
"ES_27","La Rioja",
"ES_29","Madrid",
"ES_31","Murcia",
"ES_32","Navarra",
"ES_34","Asturias",
"ES_39","Cantabria",
"ES_51","Andalucia",
"ES_52","Aragon",
"ES_53","Canarias",
"ES_54","Castilla-La Mancha",
"ES_55","Castilla y Leon",
"ES_56","Cataluna",
"ES_57","Extremadura",
"ES_58","Galicia",
"ES_59","Pais Vasco",
"ES_60","Comunidad Valenciana",
"ET_02","Amhara",
"ET_07","Somali",
"ET_08","Gambella",
"ET_10","Addis Abeba",
"ET_11","Southern",
"ET_12","Tigray",
"ET_13","Benishangul",
"ET_14","Afar",
"ET_44","Adis Abeba",
"ET_45","Afar",
"ET_46","Amara",
"ET_47","Binshangul Gumuz",
"ET_48","Dire Dawa",
"ET_49","Gambela Hizboch",
"ET_50","Hareri Hizb",
"ET_51","Oromiya",
"ET_52","Sumale",
"ET_53","Tigray",
"ET_54","YeDebub Biheroch Bihereseboch na Hizboch",
"FI_01","Iland",
"FI_06","Lapland",
"FI_08","Oulu",
"FI_13","Southern Finland",
"FI_14","Eastern Finland",
"FI_15","Western Finland",
"FJ_01","Central",
"FJ_02","Eastern",
"FJ_03","Northern",
"FJ_04","Rotuma",
"FJ_05","Western",
"FM_01","Kosrae",
"FM_02","Pohnpei",
"FM_03","Chuuk",
"FM_04","Yap",
"FR_97","Aquitaine",
"FR_98","Auvergne",
"FR_99","Basse-Normandie",
"FR_A1","Bourgogne",
"FR_A2","Bretagne",
"FR_A3","Centre",
"FR_A4","Champagne-Ardenne",
"FR_A5","Corse",
"FR_A6","Franche-Comte",
"FR_A7","Haute-Normandie",
"FR_A8","Ile-de-France",
"FR_A9","Languedoc-Roussillon",
"FR_B1","Limousin",
"FR_B2","Lorraine",
"FR_B3","Midi-Pyrenees",
"FR_B4","Nord-Pas-de-Calais",
"FR_B5","Pays de la Loire",
"FR_B6","Picardie",
"FR_B7","Poitou-Charentes",
"FR_B8","Provence-Alpes-Cote d'Azur",
"FR_B9","Rhone-Alpes",
"FR_C1","Alsace",
"GA_01","Estuaire",
"GA_02","Haut-Ogooue",
"GA_03","Moyen-Ogooue",
"GA_04","Ngounie",
"GA_05","Nyanga",
"GA_06","Ogooue-Ivindo",
"GA_07","Ogooue-Lolo",
"GA_08","Ogooue-Maritime",
"GA_09","Woleu-Ntem",
"GB_01","Avon",
"GB_03","Berkshire",
"GB_07","Cleveland",
"GB_08","Cornwall",
"GB_09","Cumbria",
"GB_17","Greater London",
"GB_18","Greater Manchester",
"GB_20","Hereford and Worcester",
"GB_22","Humberside",
"GB_28","Merseyside",
"GB_37","South Yorkshire",
"GB_41","Tyne and Wear",
"GB_43","West Midlands",
"GB_45","West Yorkshire",
"GB_79","Central",
"GB_82","Grampian",
"GB_84","Lothian",
"GB_87","Strathclyde",
"GB_88","Tayside",
"GB_90","Clwyd",
"GB_91","Dyfed",
"GB_92","Gwent",
"GB_94","Mid Glamorgan",
"GB_96","South Glamorgan",
"GB_97","West Glamorgan",
"GB_A1","Barking and Dagenham",
"GB_A2","Barnet",
"GB_A3","Barnsley",
"GB_A4","Bath and North East Somerset",
"GB_A5","Bedfordshire",
"GB_A6","Bexley",
"GB_A7","Birmingham",
"GB_A8","Blackburn with Darwen",
"GB_A9","Blackpool",
"GB_B1","Bolton",
"GB_B2","Bournemouth",
"GB_B3","Bracknell Forest",
"GB_B4","Bradford",
"GB_B5","Brent",
"GB_B6","Brighton and Hove",
"GB_B7","Bristol, City of",
"GB_B8","Bromley",
"GB_B9","Buckinghamshire",
"GB_C1","Bury",
"GB_C2","Calderdale",
"GB_C3","Cambridgeshire",
"GB_C4","Camden",
"GB_C5","Cheshire",
"GB_C7","Coventry",
"GB_C8","Croydon",
"GB_D1","Darlington",
"GB_D2","Derby",
"GB_D3","Derbyshire",
"GB_D4","Devon",
"GB_D5","Doncaster",
"GB_D6","Dorset",
"GB_D7","Dudley",
"GB_D8","Durham",
"GB_D9","Ealing",
"GB_E1","East Riding of Yorkshire",
"GB_E2","East Sussex",
"GB_E3","Enfield",
"GB_E4","Essex",
"GB_E5","Gateshead",
"GB_E6","Gloucestershire",
"GB_E7","Greenwich",
"GB_E8","Hackney",
"GB_E9","Halton",
"GB_F1","Hammersmith and Fulham",
"GB_F2","Hampshire",
"GB_F3","Haringey",
"GB_F4","Harrow",
"GB_F5","Hartlepool",
"GB_F6","Havering",
"GB_F7","Herefordshire",
"GB_F8","Hertford",
"GB_F9","Hillingdon",
"GB_G1","Hounslow",
"GB_G2","Isle of Wight",
"GB_G3","Islington",
"GB_G4","Kensington and Chelsea",
"GB_G5","Kent",
"GB_G6","Kingston upon Hull, City of",
"GB_G7","Kingston upon Thames",
"GB_G8","Kirklees",
"GB_G9","Knowsley",
"GB_H1","Lambeth",
"GB_H2","Lancashire",
"GB_H3","Leeds",
"GB_H4","Leicester",
"GB_H5","Leicestershire",
"GB_H6","Lewisham",
"GB_H7","Lincolnshire",
"GB_H8","Liverpool",
"GB_H9","London, City of",
"GB_I1","Luton",
"GB_I2","Manchester",
"GB_I3","Medway",
"GB_I4","Merton",
"GB_I5","Middlesbrough",
"GB_I6","Milton Keynes",
"GB_I7","Newcastle upon Tyne",
"GB_I8","Newham",
"GB_I9","Norfolk",
"GB_J1","Northamptonshire",
"GB_J2","North East Lincolnshire",
"GB_J3","North Lincolnshire",
"GB_J4","North Somerset",
"GB_J5","North Tyneside",
"GB_J6","Northumberland",
"GB_J7","North Yorkshire",
"GB_J8","Nottingham",
"GB_J9","Nottinghamshire",
"GB_K1","Oldham",
"GB_K2","Oxfordshire",
"GB_K3","Peterborough",
"GB_K4","Plymouth",
"GB_K5","Poole",
"GB_K6","Portsmouth",
"GB_K7","Reading",
"GB_K8","Redbridge",
"GB_K9","Redcar and Cleveland",
"GB_L1","Richmond upon Thames",
"GB_L2","Rochdale",
"GB_L3","Rotherham",
"GB_L4","Rutland",
"GB_L5","Salford",
"GB_L6","Shropshire",
"GB_L7","Sandwell",
"GB_L8","Sefton",
"GB_L9","Sheffield",
"GB_M1","Slough",
"GB_M2","Solihull",
"GB_M3","Somerset",
"GB_M4","Southampton",
"GB_M5","Southend-on-Sea",
"GB_M6","South Gloucestershire",
"GB_M7","South Tyneside",
"GB_M8","Southwark",
"GB_M9","Staffordshire",
"GB_N1","St. Helens",
"GB_N2","Stockport",
"GB_N3","Stockton-on-Tees",
"GB_N4","Stoke-on-Trent",
"GB_N5","Suffolk",
"GB_N6","Sunderland",
"GB_N7","Surrey",
"GB_N8","Sutton",
"GB_N9","Swindon",
"GB_O1","Tameside",
"GB_O2","Telford and Wrekin",
"GB_O3","Thurrock",
"GB_O4","Torbay",
"GB_O5","Tower Hamlets",
"GB_O6","Trafford",
"GB_O7","Wakefield",
"GB_O8","Walsall",
"GB_O9","Waltham Forest",
"GB_P1","Wandsworth",
"GB_P2","Warrington",
"GB_P3","Warwickshire",
"GB_P4","West Berkshire",
"GB_P5","Westminster",
"GB_P6","West Sussex",
"GB_P7","Wigan",
"GB_P8","Wiltshire",
"GB_P9","Windsor and Maidenhead",
"GB_Q1","Wirral",
"GB_Q2","Wokingham",
"GB_Q3","Wolverhampton",
"GB_Q4","Worcestershire",
"GB_Q5","York",
"GB_Q6","Antrim",
"GB_Q7","Ards",
"GB_Q8","Armagh",
"GB_Q9","Ballymena",
"GB_R1","Ballymoney",
"GB_R2","Banbridge",
"GB_R3","Belfast",
"GB_R4","Carrickfergus",
"GB_R5","Castlereagh",
"GB_R6","Coleraine",
"GB_R7","Cookstown",
"GB_R8","Craigavon",
"GB_R9","Down",
"GB_S1","Dungannon",
"GB_S2","Fermanagh",
"GB_S3","Larne",
"GB_S4","Limavady",
"GB_S5","Lisburn",
"GB_S6","Derry",
"GB_S7","Magherafelt",
"GB_S8","Moyle",
"GB_S9","Newry and Mourne",
"GB_T1","Newtownabbey",
"GB_T2","North Down",
"GB_T3","Omagh",
"GB_T4","Strabane",
"GB_T5","Aberdeen City",
"GB_T6","Aberdeenshire",
"GB_T7","Angus",
"GB_T8","Argyll and Bute",
"GB_T9","Scottish Borders, The",
"GB_U1","Clackmannanshire",
"GB_U2","Dumfries and Galloway",
"GB_U3","Dundee City",
"GB_U4","East Ayrshire",
"GB_U5","East Dunbartonshire",
"GB_U6","East Lothian",
"GB_U7","East Renfrewshire",
"GB_U8","Edinburgh, City of",
"GB_U9","Falkirk",
"GB_V1","Fife",
"GB_V2","Glasgow City",
"GB_V3","Highland",
"GB_V4","Inverclyde",
"GB_V5","Midlothian",
"GB_V6","Moray",
"GB_V7","North Ayrshire",
"GB_V8","North Lanarkshire",
"GB_V9","Orkney",
"GB_W1","Perth and Kinross",
"GB_W2","Renfrewshire",
"GB_W3","Shetland Islands",
"GB_W4","South Ayrshire",
"GB_W5","South Lanarkshire",
"GB_W6","Stirling",
"GB_W7","West Dunbartonshire",
"GB_W8","Eilean Siar",
"GB_W9","West Lothian",
"GB_X1","Isle of Anglesey",
"GB_X2","Blaenau Gwent",
"GB_X3","Bridgend",
"GB_X4","Caerphilly",
"GB_X5","Cardiff",
"GB_X6","Ceredigion",
"GB_X7","Carmarthenshire",
"GB_X8","Conwy",
"GB_X9","Denbighshire",
"GB_Y1","Flintshire",
"GB_Y2","Gwynedd",
"GB_Y3","Merthyr Tydfil",
"GB_Y4","Monmouthshire",
"GB_Y5","Neath Port Talbot",
"GB_Y6","Newport",
"GB_Y7","Pembrokeshire",
"GB_Y8","Powys",
"GB_Y9","Rhondda Cynon Taff",
"GB_Z1","Swansea",
"GB_Z2","Torfaen",
"GB_Z3","Vale of Glamorgan, The",
"GB_Z4","Wrexham",
"GD_01","Saint Andrew",
"GD_02","Saint David",
"GD_03","Saint George",
"GD_04","Saint John",
"GD_05","Saint Mark",
"GD_06","Saint Patrick",
"GE_01","Abashis Raioni",
"GE_02","Abkhazia",
"GE_03","Adigenis Raioni",
"GE_04","Ajaria",
"GE_05","Akhalgoris Raioni",
"GE_06","Akhalk'alak'is Raioni",
"GE_07","Akhalts'ikhis Raioni",
"GE_08","Akhmetis Raioni",
"GE_09","Ambrolauris Raioni",
"GE_10","Aspindzis Raioni",
"GE_11","Baghdat'is Raioni",
"GE_12","Bolnisis Raioni",
"GE_13","Borjomis Raioni",
"GE_14","Chiat'ura",
"GE_15","Ch'khorotsqus Raioni",
"GE_16","Ch'okhatauris Raioni",
"GE_17","Dedop'listsqaros Raioni",
"GE_18","Dmanisis Raioni",
"GE_19","Dushet'is Raioni",
"GE_20","Gardabanis Raioni",
"GE_21","Gori",
"GE_22","Goris Raioni",
"GE_23","Gurjaanis Raioni",
"GE_24","Javis Raioni",
"GE_25","K'arelis Raioni",
"GE_26","Kaspis Raioni",
"GE_27","Kharagaulis Raioni",
"GE_28","Khashuris Raioni",
"GE_29","Khobis Raioni",
"GE_30","Khonis Raioni",
"GE_31","K'ut'aisi",
"GE_32","Lagodekhis Raioni",
"GE_33","Lanch'khut'is Raioni",
"GE_34","Lentekhis Raioni",
"GE_35","Marneulis Raioni",
"GE_36","Martvilis Raioni",
"GE_37","Mestiis Raioni",
"GE_38","Mts'khet'is Raioni",
"GE_39","Ninotsmindis Raioni",
"GE_40","Onis Raioni",
"GE_41","Ozurget'is Raioni",
"GE_42","P'ot'i",
"GE_43","Qazbegis Raioni",
"GE_44","Qvarlis Raioni",
"GE_45","Rust'avi",
"GE_46","Sach'kheris Raioni",
"GE_47","Sagarejos Raioni",
"GE_48","Samtrediis Raioni",
"GE_49","Senakis Raioni",
"GE_50","Sighnaghis Raioni",
"GE_51","T'bilisi",
"GE_52","T'elavis Raioni",
"GE_53","T'erjolis Raioni",
"GE_54","T'et'ritsqaros Raioni",
"GE_55","T'ianet'is Raioni",
"GE_56","Tqibuli",
"GE_57","Ts'ageris Raioni",
"GE_58","Tsalenjikhis Raioni",
"GE_59","Tsalkis Raioni",
"GE_60","Tsqaltubo",
"GE_61","Vanis Raioni",
"GE_62","Zestap'onis Raioni",
"GE_63","Zugdidi",
"GE_64","Zugdidis Raioni",
"GH_01","Greater Accra",
"GH_02","Ashanti",
"GH_03","Brong-Ahafo",
"GH_04","Central",
"GH_05","Eastern",
"GH_06","Northern",
"GH_08","Volta",
"GH_09","Western",
"GH_10","Upper East",
"GH_11","Upper West",
"GL_01","Nordgronland",
"GL_02","Ostgronland",
"GL_03","Vestgronland",
"GM_01","Banjul",
"GM_02","Lower River",
"GM_03","MacCarthy Island",
"GM_04","Upper River",
"GM_05","Western",
"GM_07","North Bank",
"GN_01","Beyla",
"GN_02","Boffa",
"GN_03","Boke",
"GN_04","Conakry",
"GN_05","Dabola",
"GN_06","Dalaba",
"GN_07","Dinguiraye",
"GN_09","Faranah",
"GN_10","Forecariah",
"GN_11","Fria",
"GN_12","Gaoual",
"GN_13","Gueckedou",
"GN_15","Kerouane",
"GN_16","Kindia",
"GN_17","Kissidougou",
"GN_18","Koundara",
"GN_19","Kouroussa",
"GN_21","Macenta",
"GN_22","Mali",
"GN_23","Mamou",
"GN_25","Pita",
"GN_27","Telimele",
"GN_28","Tougue",
"GN_29","Yomou",
"GN_30","Coyah",
"GN_31","Dubreka",
"GN_32","Kankan",
"GN_33","Koubia",
"GN_34","Labe",
"GN_35","Lelouma",
"GN_36","Lola",
"GN_37","Mandiana",
"GN_38","Nzerekore",
"GN_39","Siguiri",
"GQ_03","Annobon",
"GQ_04","Bioko Norte",
"GQ_05","Bioko Sur",
"GQ_06","Centro Sur",
"GQ_07","Kie-Ntem",
"GQ_08","Litoral",
"GQ_09","Wele-Nzas",
"GR_01","Evros",
"GR_02","Rodhopi",
"GR_03","Xanthi",
"GR_04","Drama",
"GR_05","Serrai",
"GR_06","Kilkis",
"GR_07","Pella",
"GR_08","Florina",
"GR_09","Kastoria",
"GR_10","Grevena",
"GR_11","Kozani",
"GR_12","Imathia",
"GR_13","Thessaloniki",
"GR_14","Kavala",
"GR_15","Khalkidhiki",
"GR_16","Pieria",
"GR_17","Ioannina",
"GR_18","Thesprotia",
"GR_19","Preveza",
"GR_20","Arta",
"GR_21","Larisa",
"GR_22","Trikala",
"GR_23","Kardhitsa",
"GR_24","Magnisia",
"GR_25","Kerkira",
"GR_26","Levkas",
"GR_27","Kefallinia",
"GR_28","Zakinthos",
"GR_29","Fthiotis",
"GR_30","Evritania",
"GR_31","Aitolia kai Akarnania",
"GR_32","Fokis",
"GR_33","Voiotia",
"GR_34","Evvoia",
"GR_35","Attiki",
"GR_36","Argolis",
"GR_37","Korinthia",
"GR_38","Akhaia",
"GR_39","Ilia",
"GR_40","Messinia",
"GR_41","Arkadhia",
"GR_42","Lakonia",
"GR_43","Khania",
"GR_44","Rethimni",
"GR_45","Iraklion",
"GR_46","Lasithi",
"GR_47","Dhodhekanisos",
"GR_48","Samos",
"GR_49","Kikladhes",
"GR_50","Khios",
"GR_51","Lesvos",
"GT_01","Alta Verapaz",
"GT_02","Baja Verapaz",
"GT_03","Chimaltenango",
"GT_04","Chiquimula",
"GT_05","El Progreso",
"GT_06","Escuintla",
"GT_07","Guatemala",
"GT_08","Huehuetenango",
"GT_09","Izabal",
"GT_10","Jalapa",
"GT_11","Jutiapa",
"GT_12","Peten",
"GT_13","Quetzaltenango",
"GT_14","Quiche",
"GT_15","Retalhuleu",
"GT_16","Sacatepequez",
"GT_17","San Marcos",
"GT_18","Santa Rosa",
"GT_19","Solola",
"GT_20","Suchitepequez",
"GT_21","Totonicapan",
"GT_22","Zacapa",
"GW_01","Bafata",
"GW_02","Quinara",
"GW_04","Oio",
"GW_05","Bolama",
"GW_06","Cacheu",
"GW_07","Tombali",
"GW_10","Gabu",
"GW_11","Bissau",
"GW_12","Biombo",
"GY_10","Barima-Waini",
"GY_11","Cuyuni-Mazaruni",
"GY_12","Demerara-Mahaica",
"GY_13","East Berbice-Corentyne",
"GY_14","Essequibo Islands-West Demerara",
"GY_15","Mahaica-Berbice",
"GY_16","Pomeroon-Supenaam",
"GY_17","Potaro-Siparuni",
"GY_18","Upper Demerara-Berbice",
"GY_19","Upper Takutu-Upper Essequibo",
"HN_01","Atlantida",
"HN_02","Choluteca",
"HN_03","Colon",
"HN_04","Comayagua",
"HN_05","Copan",
"HN_06","Cortes",
"HN_07","El Paraiso",
"HN_08","Francisco Morazan",
"HN_09","Gracias a Dios",
"HN_10","Intibuca",
"HN_11","Islas de la Bahia",
"HN_12","La Paz",
"HN_13","Lempira",
"HN_14","Ocotepeque",
"HN_15","Olancho",
"HN_16","Santa Barbara",
"HN_17","Valle",
"HN_18","Yoro",
"HR_01","Bjelovarsko-Bilogorska",
"HR_02","Brodsko-Posavska",
"HR_03","Dubrovacko-Neretvanska",
"HR_04","Istarska",
"HR_05","Karlovacka",
"HR_06","Koprivnicko-Krizevacka",
"HR_07","Krapinsko-Zagorska",
"HR_08","Licko-Senjska",
"HR_09","Medimurska",
"HR_10","Osjecko-Baranjska",
"HR_11","Pozesko-Slavonska",
"HR_12","Primorsko-Goranska",
"HR_13","Sibensko-Kninska",
"HR_14","Sisacko-Moslavacka",
"HR_15","Splitsko-Dalmatinska",
"HR_16","Varazdinska",
"HR_17","Viroviticko-Podravska",
"HR_18","Vukovarsko-Srijemska",
"HR_19","Zadarska",
"HR_20","Zagrebacka",
"HR_21","Grad Zagreb",
"HT_03","Nord-Ouest",
"HT_06","Artibonite",
"HT_07","Centre",
"HT_08","Grand' Anse",
"HT_09","Nord",
"HT_10","Nord-Est",
"HT_11","Ouest",
"HT_12","Sud",
"HT_13","Sud-Est",
"HU_01","Bacs-Kiskun",
"HU_02","Baranya",
"HU_03","Bekes",
"HU_04","Borsod-Abauj-Zemplen",
"HU_05","Budapest",
"HU_06","Csongrad",
"HU_07","Debrecen",
"HU_08","Fejer",
"HU_09","Gyor-Moson-Sopron",
"HU_10","Hajdu-Bihar",
"HU_11","Heves",
"HU_12","Komarom-Esztergom",
"HU_13","Miskolc",
"HU_14","Nograd",
"HU_15","Pecs",
"HU_16","Pest",
"HU_17","Somogy",
"HU_18","Szabolcs-Szatmar-Bereg",
"HU_19","Szeged",
"HU_20","Jasz-Nagykun-Szolnok",
"HU_21","Tolna",
"HU_22","Vas",
"HU_23","Veszprem",
"HU_24","Zala",
"HU_25","Gyor",
"HU_26","Bekescsaba",
"HU_27","Dunaujvaros",
"HU_28","Eger",
"HU_29","Hodmezovasarhely",
"HU_30","Kaposvar",
"HU_31","Kecskemet",
"HU_32","Nagykanizsa",
"HU_33","Nyiregyhaza",
"HU_34","Sopron",
"HU_35","Szekesfehervar",
"HU_36","Szolnok",
"HU_37","Szombathely",
"HU_38","Tatabanya",
"HU_39","Veszprem",
"HU_40","Zalaegerszeg",
"ID_01","Aceh",
"ID_02","Bali",
"ID_03","Bengkulu",
"ID_04","Jakarta Raya",
"ID_05","Jambi",
"ID_07","Jawa Tengah",
"ID_08","Jawa Timur",
"ID_09","Papua",
"ID_10","Yogyakarta",
"ID_11","Kalimantan Barat",
"ID_12","Kalimantan Selatan",
"ID_13","Kalimantan Tengah",
"ID_14","Kalimantan Timur",
"ID_15","Lampung",
"ID_17","Nusa Tenggara Barat",
"ID_18","Nusa Tenggara Timur",
"ID_19","Riau",
"ID_20","Sulawesi Selatan",
"ID_21","Sulawesi Tengah",
"ID_22","Sulawesi Tenggara",
"ID_24","Sumatera Barat",
"ID_26","Sumatera Utara",
"ID_28","Maluku",
"ID_29","Maluku Utara",
"ID_30","Jawa Barat",
"ID_31","Sulawesi Utara",
"ID_32","Sumatera Selatan",
"ID_33","Banten",
"ID_34","Gorontalo",
"ID_35","Kepulauan Bangka Belitung",
"IE_01","Carlow",
"IE_02","Cavan",
"IE_03","Clare",
"IE_04","Cork",
"IE_06","Donegal",
"IE_07","Dublin",
"IE_10","Galway",
"IE_11","Kerry",
"IE_12","Kildare",
"IE_13","Kilkenny",
"IE_14","Leitrim",
"IE_15","Laois",
"IE_16","Limerick",
"IE_18","Longford",
"IE_19","Louth",
"IE_20","Mayo",
"IE_21","Meath",
"IE_22","Monaghan",
"IE_23","Offaly",
"IE_24","Roscommon",
"IE_25","Sligo",
"IE_26","Tipperary",
"IE_27","Waterford",
"IE_29","Westmeath",
"IE_30","Wexford",
"IE_31","Wicklow",
"IL_01","HaDarom",
"IL_02","HaMerkaz",
"IL_03","HaZafon",
"IL_04","Hefa",
"IL_05","Tel Aviv",
"IL_06","Yerushalayim",
"IN_01","Andaman and Nicobar Islands",
"IN_02","Andhra Pradesh",
"IN_03","Assam",
"IN_05","Chandigarh",
"IN_06","Dadra and Nagar Haveli",
"IN_07","Delhi",
"IN_09","Gujarat",
"IN_10","Haryana",
"IN_11","Himachal Pradesh",
"IN_12","Jammu and Kashmir",
"IN_13","Kerala",
"IN_14","Lakshadweep",
"IN_16","Maharashtra",
"IN_17","Manipur",
"IN_18","Meghalaya",
"IN_19","Karnataka",
"IN_20","Nagaland",
"IN_21","Orissa",
"IN_22","Pondicherry",
"IN_23","Punjab",
"IN_24","Rajasthan",
"IN_25","Tamil Nadu",
"IN_26","Tripura",
"IN_28","West Bengal",
"IN_29","Sikkim",
"IN_30","Arunachal Pradesh",
"IN_31","Mizoram",
"IN_32","Daman and Diu",
"IN_33","Goa",
"IN_34","Bihar",
"IN_35","Madhya Pradesh",
"IN_36","Uttar Pradesh",
"IN_37","Chhattisgarh",
"IN_38","Jharkhand",
"IN_39","Uttaranchal",
"IQ_01","Al Anbar",
"IQ_02","Al Basrah",
"IQ_03","Al Muthanna",
"IQ_04","Al Qadisiyah",
"IQ_05","As Sulaymaniyah",
"IQ_06","Babil",
"IQ_07","Baghdad",
"IQ_08","Dahuk",
"IQ_09","Dhi Qar",
"IQ_10","Diyala",
"IQ_11","Arbil",
"IQ_12","Karbala'",
"IQ_13","At Ta'mim",
"IQ_14","Maysan",
"IQ_15","Ninawa",
"IQ_16","Wasit",
"IQ_17","An Najaf",
"IQ_18","Salah ad Din",
"IR_01","Azarbayjan-e Bakhtari",
"IR_02","Azarbayjan-e Khavari",
"IR_03","Chahar Mahall va Bakhtiari",
"IR_04","Sistan va Baluchestan",
"IR_05","Kohkiluyeh va Buyer Ahmadi",
"IR_07","Fars",
"IR_08","Gilan",
"IR_09","Hamadan",
"IR_10","Ilam",
"IR_11","Hormozgan",
"IR_13","Bakhtaran",
"IR_15","Khuzestan",
"IR_16","Kordestan",
"IR_22","Bushehr",
"IR_23","Lorestan",
"IR_25","Semnan",
"IR_26","Tehran",
"IR_28","Esfahan",
"IR_29","Kerman",
"IR_30","Khorasan",
"IR_31","Yazd",
"IR_34","Markazi",
"IR_35","Mazandaran",
"IR_36","Zanjan",
"IR_37","Golestan",
"IR_38","Qazvin",
"IR_39","Qom",
"IS_01","Akranes",
"IS_02","Akureyri",
"IS_03","Arnessysla",
"IS_04","Austur-Bardastrandarsysla",
"IS_05","Austur-Hunavatnssysla",
"IS_06","Austur-Skaftafellssysla",
"IS_07","Borgarfjardarsysla",
"IS_08","Dalasysla",
"IS_09","Eyjafjardarsysla",
"IS_10","Gullbringusysla",
"IS_11","Hafnarfjordur",
"IS_12","Husavik",
"IS_13","Isafjordur",
"IS_14","Keflavik",
"IS_15","Kjosarsysla",
"IS_16","Kopavogur",
"IS_17","Myrasysla",
"IS_18","Neskaupstadur",
"IS_19","Nordur-Isafjardarsysla",
"IS_20","Nordur-Mulasysla",
"IS_21","Nordur-Tingeyjarsysla",
"IS_22","Olafsfjordur",
"IS_23","Rangarvallasysla",
"IS_24","Reykjavik",
"IS_25","Saudarkrokur",
"IS_26","Seydisfjordur",
"IS_27","Siglufjordur",
"IS_28","Skagafjardarsysla",
"IS_29","Snafellsnes- og Hnappadalssysla",
"IS_30","Strandasysla",
"IS_31","Sudur-Mulasysla",
"IS_32","Sudur-Tingeyjarsysla",
"IS_33","Vestmannaeyjar",
"IS_34","Vestur-Bardastrandarsysla",
"IS_35","Vestur-Hunavatnssysla",
"IS_36","Vestur-Isafjardarsysla",
"IS_37","Vestur-Skaftafellssysla",
"IT_01","Abruzzi",
"IT_02","Basilicata",
"IT_03","Calabria",
"IT_04","Campania",
"IT_05","Emilia-Romagna",
"IT_06","Friuli-Venezia Giulia",
"IT_07","Lazio",
"IT_08","Liguria",
"IT_09","Lombardia",
"IT_10","Marche",
"IT_11","Molise",
"IT_12","Piemonte",
"IT_13","Puglia",
"IT_14","Sardegna",
"IT_15","Sicilia",
"IT_16","Toscana",
"IT_17","Trentino-Alto Adige",
"IT_18","Umbria",
"IT_19","Valle d'Aosta",
"IT_20","Veneto",
"JM_01","Clarendon",
"JM_02","Hanover",
"JM_04","Manchester",
"JM_07","Portland",
"JM_08","Saint Andrew",
"JM_09","Saint Ann",
"JM_10","Saint Catherine",
"JM_11","Saint Elizabeth",
"JM_12","Saint James",
"JM_13","Saint Mary",
"JM_14","Saint Thomas",
"JM_15","Trelawny",
"JM_16","Westmoreland",
"JM_17","Kingston",
"JO_02","Al Balqa'",
"JO_07","Ma",
"JO_09","Al Karak",
"JO_10","Al Mafraq",
"JO_12","At Tafilah",
"JO_13","Az Zarqa",
"JO_14","Irbid",
"JP_01","Aichi",
"JP_02","Akita",
"JP_03","Aomori",
"JP_04","Chiba",
"JP_05","Ehime",
"JP_06","Fukui",
"JP_07","Fukuoka",
"JP_08","Fukushima",
"JP_09","Gifu",
"JP_10","Gumma",
"JP_11","Hiroshima",
"JP_12","Hokkaido",
"JP_13","Hyogo",
"JP_14","Ibaraki",
"JP_15","Ishikawa",
"JP_16","Iwate",
"JP_17","Kagawa",
"JP_18","Kagoshima",
"JP_19","Kanagawa",
"JP_20","Kochi",
"JP_21","Kumamoto",
"JP_22","Kyoto",
"JP_23","Mie",
"JP_24","Miyagi",
"JP_25","Miyazaki",
"JP_26","Nagano",
"JP_27","Nagasaki",
"JP_28","Nara",
"JP_29","Niigata",
"JP_30","Oita",
"JP_31","Okayama",
"JP_32","Osaka",
"JP_33","Saga",
"JP_34","Saitama",
"JP_35","Shiga",
"JP_36","Shimane",
"JP_37","Shizuoka",
"JP_38","Tochigi",
"JP_39","Tokushima",
"JP_40","Tokyo",
"JP_41","Tottori",
"JP_42","Toyama",
"JP_43","Wakayama",
"JP_44","Yamagata",
"JP_45","Yamaguchi",
"JP_46","Yamanashi",
"JP_47","Okinawa",
"KE_01","Central",
"KE_02","Coast",
"KE_03","Eastern",
"KE_05","Nairobi Area",
"KE_06","North-Eastern",
"KE_07","Nyanza",
"KE_08","Rift Valley",
"KE_09","Western",
"KG_09","Batken",
"KH_02","Kampong Cham",
"KH_03","Kampong Chhnang",
"KH_04","Kampong Spoe",
"KH_05","Kampong Thum",
"KH_06","Kampot",
"KH_07","Kandal",
"KH_08","Kaoh Kong",
"KH_09","Kracheh",
"KH_10","Mondol Kiri",
"KH_11","Phnum Penh",
"KH_12","Pouthisat",
"KH_13","Preah Vihear",
"KH_14","Prey Veng",
"KH_15","Rotanokiri",
"KH_16","Siemreab-Otdar Meanchey",
"KH_17","Stoeng Treng",
"KH_18","Svay Rieng",
"KH_19","Takev",
"KH_29","Batdambang",
"KH_30","Pailin",
"KI_01","Gilbert Islands",
"KI_02","Line Islands",
"KI_03","Phoenix Islands",
"KM_01","Anjouan",
"KM_02","Grande Comore",
"KM_03","Moheli",
"KN_01","Christ Church Nichola Town",
"KN_02","Saint Anne Sandy Point",
"KN_03","Saint George Basseterre",
"KN_04","Saint George Gingerland",
"KN_05","Saint James Windward",
"KN_06","Saint John Capisterre",
"KN_07","Saint John Figtree",
"KN_08","Saint Mary Cayon",
"KN_09","Saint Paul Capisterre",
"KN_10","Saint Paul Charlestown",
"KN_11","Saint Peter Basseterre",
"KN_12","Saint Thomas Lowland",
"KN_13","Saint Thomas Middle Island",
"KN_15","Trinity Palmetto Point",
"KP_01","Chagang-do",
"KP_03","Hamgyong-namdo",
"KP_06","Hwanghae-namdo",
"KP_07","Hwanghae-bukto",
"KP_08","Kaesong-si",
"KP_09","Kangwon-do",
"KP_11","P'yongan-bukto",
"KP_12","P'yongyang-si",
"KP_13","Yanggang-do",
"KP_14","Namp'o-si",
"KP_15","P'yongan-namdo",
"KP_17","Hamgyong-bukto",
"KP_18","Najin Sonbong-si",
"KR_01","Cheju-do",
"KR_03","Cholla-bukto",
"KR_05","Ch'ungch'ong-bukto",
"KR_06","Kangwon-do",
"KR_10","Pusan-jikhalsi",
"KR_11","Seoul-t'ukpyolsi",
"KR_12","Inch'on-jikhalsi",
"KR_13","Kyonggi-do",
"KR_14","Kyongsang-bukto",
"KR_15","Taegu-jikhalsi",
"KR_16","Cholla-namdo",
"KR_17","Ch'ungch'ong-namdo",
"KR_18","Kwangju-jikhalsi",
"KR_19","Taejon-jikhalsi",
"KR_20","Kyongsang-namdo",
"KR_21","Ulsan-gwangyoksi",
"KW_01","Al Ahmadi",
"KW_02","Al Kuwayt",
"KW_03","Hawalli",
"KY_01","Creek",
"KY_02","Eastern",
"KY_03","Midland",
"KY_04","South Town",
"KY_05","Spot Bay",
"KY_06","Stake Bay",
"KY_07","West End",
"KY_08","Western",
"KZ_01","Almaty",
"KZ_02","Almaty City",
"KZ_03","Aqmola",
"KZ_04","Aqtebe",
"KZ_05","Astana",
"KZ_06","Atyrau",
"KZ_07","West Kazakhstan",
"KZ_08","Bayqonyr",
"KZ_09","Mangghystau",
"KZ_10","South Kazakhstan",
"KZ_11","Pavlodar",
"KZ_12","Qaraghandy",
"KZ_13","Qostanay",
"KZ_14","Qyzylorda",
"KZ_15","East Kazakhstan",
"KZ_16","North Kazakhstan",
"KZ_17","Zhambyl",
"LA_01","Attapu",
"LA_02","Champasak",
"LA_03","Houaphan",
"LA_04","Khammouan",
"LA_05","Louang Namtha",
"LA_06","Louangphrabang",
"LA_07","Oudomxai",
"LA_08","Phongsali",
"LA_09","Saravan",
"LA_10","Savannakhet",
"LA_11","Vientiane",
"LA_13","Xaignabouri",
"LA_14","Xiangkhoang",
"LB_01","Beqaa",
"LB_03","Liban-Nord",
"LB_04","Beyrouth",
"LB_05","Mont-Liban",
"LB_06","Liban-Sud",
"LB_07","Nabatiye",
"LC_01","Anse-la-Raye",
"LC_02","Dauphin",
"LC_03","Castries",
"LC_04","Choiseul",
"LC_05","Dennery",
"LC_06","Gros-Islet",
"LC_07","Laborie",
"LC_08","Micoud",
"LC_09","Soufriere",
"LC_10","Vieux-Fort",
"LC_11","Praslin",
"LI_01","Balzers",
"LI_02","Eschen",
"LI_03","Gamprin",
"LI_04","Mauren",
"LI_05","Planken",
"LI_06","Ruggell",
"LI_07","Schaan",
"LI_08","Schellenberg",
"LI_09","Triesen",
"LI_10","Triesenberg",
"LI_11","Vaduz",
"LK_01","Amparai",
"LK_02","Anuradhapura",
"LK_03","Badulla",
"LK_04","Batticaloa",
"LK_06","Galle",
"LK_07","Hambantota",
"LK_09","Kalutara",
"LK_10","Kandy",
"LK_11","Kegalla",
"LK_12","Kurunegala",
"LK_14","Matale",
"LK_15","Matara",
"LK_16","Moneragala",
"LK_17","Nuwara Eliya",
"LK_18","Polonnaruwa",
"LK_19","Puttalam",
"LK_20","Ratnapura",
"LK_21","Trincomalee",
"LK_23","Colombo",
"LK_24","Gampaha",
"LK_25","Jaffna",
"LK_26","Mannar",
"LK_27","Mullaittivu",
"LK_28","Vavuniya",
"LR_01","Bong",
"LR_02","Grand Jide",
"LR_03","Grand Bassa",
"LR_04","Grand Cape Mount",
"LR_05","Lofa",
"LR_06","Maryland",
"LR_07","Monrovia",
"LR_08","Montserrado",
"LR_09","Nimba",
"LR_10","Sino",
"LS_10","Berea",
"LS_11","Butha-Buthe",
"LS_12","Leribe",
"LS_13","Mafeteng",
"LS_14","Maseru",
"LS_15","Mohales Hoek",
"LS_16","Mokhotlong",
"LS_17","Qachas Nek",
"LS_18","Quthing",
"LS_19","Thaba-Tseka",
"LT_56","Alytaus Apskritis",
"LT_57","Kauno Apskritis",
"LT_58","Klaipedos Apskritis",
"LT_59","Marijampoles Apskritis",
"LT_60","Panevezio Apskritis",
"LT_61","Siauliu Apskritis",
"LT_62","Taurages Apskritis",
"LT_63","Telsiu Apskritis",
"LT_64","Utenos Apskritis",
"LT_65","Vilniaus Apskritis",
"LU_01","Diekirch",
"LU_02","Grevenmacher",
"LU_03","Luxembourg",
"LV_01","Aizkraukles",
"LV_02","Aluksnes",
"LV_03","Balvu",
"LV_04","Bauskas",
"LV_05","C�su",
"LV_06","Daugavpils",
"LV_07","Daugavpils",
"LV_08","Dobeles",
"LV_09","Gulbenes",
"LV_10","Jekabpils",
"LV_11","Jelgava",
"LV_12","Jelgavas",
"LV_13","Jurmala",
"LV_14","Krelavas",
"LV_15","Kuldigas",
"LV_16","Liepeja",
"LV_17","Liepejas",
"LV_18","Limbazu",
"LV_19","Ludzas",
"LV_20","Madonas",
"LV_21","Ogres",
"LV_22","Preilu",
"LV_23","Rezekne",
"LV_24","Rezeknes",
"LV_25","Riga",
"LV_26","Rigas",
"LV_27","Saldus",
"LV_28","Talsu",
"LV_29","Tukuma",
"LV_30","Valkas",
"LV_31","Valmieras",
"LV_32","Ventspils",
"LV_33","Ventspils",
"LY_03","Al",
"LY_05","Al Jufrah",
"LY_08","Al Kufrah",
"LY_13","Ash Shati'",
"LY_30","Murzuq",
"LY_34","Sabha",
"LY_41","Tarhunah",
"LY_42","Tubruq",
"LY_45","Zlitan",
"LY_47","Ajdabiya",
"LY_48","Al Fatih",
"LY_49","Al Jabal al Akhdar",
"LY_50","Al Khums",
"LY_51","An Nuqat al Khams",
"LY_52","Awbari",
"LY_53","Az Zawiyah",
"LY_54","Banghazi",
"LY_55","Darnah",
"LY_56","Ghadamis",
"LY_57","Gharyan",
"LY_58","Misratah",
"LY_59","Sawfajjin",
"LY_60","Surt",
"LY_61","Tarabulus",
"LY_62","Yafran",
"MA_01","Agadir",
"MA_02","Al Hoceima",
"MA_03","Azilal",
"MA_04","Ben Slimane",
"MA_05","Beni Mellal",
"MA_06","Boulemane",
"MA_07","Casablanca",
"MA_08","Chaouen",
"MA_09","El Jadida",
"MA_10","El Kelaa des Srarhna",
"MA_11","Er Rachidia",
"MA_12","Essaouira",
"MA_13","Fes",
"MA_14","Figuig",
"MA_15","Kenitra",
"MA_16","Khemisset",
"MA_17","Khenifra",
"MA_18","Khouribga",
"MA_19","Marrakech",
"MA_20","Meknes",
"MA_21","Nador",
"MA_22","Ouarzazate",
"MA_23","Oujda",
"MA_24","Rabat-Sale",
"MA_25","Safi",
"MA_26","Settat",
"MA_27","Tanger",
"MA_29","Tata",
"MA_30","Taza",
"MA_32","Tiznit",
"MA_33","Guelmim",
"MA_34","Ifrane",
"MA_35","Laayoune",
"MA_36","Tan-Tan",
"MA_37","Taounate",
"MA_38","Sidi Kacem",
"MA_39","Taroudannt",
"MA_40","Tetouan",
"MA_41","Larache",
"MC_01","La Condamine",
"MC_02","Monaco",
"MC_03","Monte-Carlo",
"MD_46","Balti",
"MD_47","Cahul",
"MD_48","Chisinau",
"MD_49","Stinga Nistrului",
"MD_50","Edinet",
"MD_51","Gagauzia",
"MD_52","Lapusna",
"MD_53","Orhei",
"MD_54","Soroca",
"MD_55","Tighina",
"MD_56","Ungheni",
"MG_01","Antsiranana",
"MG_02","Fianarantsoa",
"MG_03","Mahajanga",
"MG_04","Toamasina",
"MG_05","Antananarivo",
"MG_06","Toliara",
"MK_01","Aracinovo",
"MK_02","Bac",
"MK_03","Belcista",
"MK_04","Berovo",
"MK_05","Bistrica",
"MK_06","Bitola",
"MK_07","Blatec",
"MK_08","Bogdanci",
"MK_09","Bogomila",
"MK_10","Bogovinje",
"MK_11","Bosilovo",
"MK_12","Brvenica",
"MK_13","Cair",
"MK_14","Capari",
"MK_15","Caska",
"MK_16","Cegrane",
"MK_17","Centar",
"MK_18","Centar Zupa",
"MK_19","Cesinovo",
"MK_20","Cucer-Sandevo",
"MK_21","Debar",
"MK_22","Delcevo",
"MK_23","Delogozdi",
"MK_24","Demir Hisar",
"MK_25","Demir Kapija",
"MK_26","Dobrusevo",
"MK_27","Dolna Banjica",
"MK_28","Dolneni",
"MK_29","Dorce Petrov",
"MK_30","Drugovo",
"MK_31","Dzepciste",
"MK_32","Gazi Baba",
"MK_33","Gevgelija",
"MK_34","Gostivar",
"MK_35","Gradsko",
"MK_36","Ilinden",
"MK_37","Izvor",
"MK_38","Jegunovce",
"MK_39","Kamenjane",
"MK_40","Karbinci",
"MK_41","Karpos",
"MK_42","Kavadarci",
"MK_43","Kicevo",
"MK_44","Kisela Voda",
"MK_45","Klecevce",
"MK_46","Kocani",
"MK_47","Konce",
"MK_48","Kondovo",
"MK_49","Konopiste",
"MK_50","Kosel",
"MK_51","Kratovo",
"MK_52","Kriva Palanka",
"MK_53","Krivogastani",
"MK_54","Krusevo",
"MK_55","Kuklis",
"MK_56","Kukurecani",
"MK_57","Kumanovo",
"MK_58","Labunista",
"MK_59","Lipkovo",
"MK_60","Lozovo",
"MK_61","Lukovo",
"MK_62","Makedonska Kamenica",
"MK_63","Makedonski Brod",
"MK_64","Mavrovi Anovi",
"MK_65","Meseista",
"MK_66","Miravci",
"MK_67","Mogila",
"MK_68","Murtino",
"MK_69","Negotino",
"MK_70","Negotino-Polosko",
"MK_71","Novaci",
"MK_72","Novo Selo",
"MK_73","Oblesevo",
"MK_74","Ohrid",
"MK_75","Orasac",
"MK_76","Orizari",
"MK_77","Oslomej",
"MK_78","Pehcevo",
"MK_79","Petrovec",
"MK_80","Plasnica",
"MK_81","Podares",
"MK_82","Prilep",
"MK_83","Probistip",
"MK_84","Radovis",
"MK_85","Rankovce",
"MK_86","Resen",
"MK_87","Rosoman",
"MK_88","Rostusa",
"MK_89","Samokov",
"MK_90","Saraj",
"MK_91","Sipkovica",
"MK_92","Sopiste",
"MK_93","Sopotnica",
"MK_94","Srbinovo",
"MK_95","Staravina",
"MK_96","Star Dojran",
"MK_97","Staro Nagoricane",
"MK_98","Stip",
"MK_99","Struga",
"MK_A1","Strumica",
"MK_A2","Studenicani",
"MK_A3","Suto Orizari",
"MK_A4","Sveti Nikole",
"MK_A5","Tearce",
"MK_A6","Tetovo",
"MK_A7","Topolcani",
"MK_A8","Valandovo",
"MK_A9","Vasilevo",
"MK_B1","Veles",
"MK_B2","Velesta",
"MK_B3","Vevcani",
"MK_B4","Vinica",
"MK_B5","Vitoliste",
"MK_B6","Vranestica",
"MK_B7","Vrapciste",
"MK_B8","Vratnica",
"MK_B9","Vrutok",
"MK_C1","Zajas",
"MK_C2","Zelenikovo",
"MK_C3","Zelino",
"MK_C4","Zitose",
"MK_C5","Zletovo",
"MK_C6","Zrnovci",
"ML_01","Bamako",
"ML_03","Kayes",
"ML_04","Mopti",
"ML_05","Segou",
"ML_06","Sikasso",
"ML_07","Koulikoro",
"ML_08","Tombouctou",
"ML_09","Gao",
"ML_10","Kidal",
"MM_01","Rakhine State",
"MM_02","Chin State",
"MM_03","Irrawaddy",
"MM_04","Kachin State",
"MM_05","Karan State",
"MM_06","Kayah State",
"MM_07","Magwe",
"MM_08","Mandalay",
"MM_09","Pegu",
"MM_10","Sagaing",
"MM_11","Shan State",
"MM_12","Tenasserim",
"MM_13","Mon State",
"MM_14","Rangoon",
"MN_01","Arhangay",
"MN_02","Bayanhongor",
"MN_03","Bayan-Olgiy",
"MN_05","Darhan",
"MN_06","Dornod",
"MN_07","Dornogovi",
"MN_08","Dundgovi",
"MN_09","Dzavhan",
"MN_10","Govi-Altay",
"MN_11","Hentiy",
"MN_12","Hovd",
"MN_13","Hovsgol",
"MN_14","Omnogovi",
"MN_15","Ovorhangay",
"MN_16","Selenge",
"MN_17","Suhbaatar",
"MN_18","Tov",
"MN_19","Uvs",
"MN_20","Ulaanbaatar",
"MN_21","Bulgan",
"MN_22","Erdenet",
"MN_23","Darhan Uul",
"MN_24","Govi-Sumber",
"MN_25","Orhon",
"MO_01","Ilhas",
"MO_02","Macau",
"MR_01","Hodh Ech Chargui",
"MR_02","Hodh El Gharbi",
"MR_03","Assaba",
"MR_04","Gorgol",
"MR_05","Brakna",
"MR_06","Trarza",
"MR_07","Adrar",
"MR_08","Dakhlet Nouadhibou",
"MR_09","Tagant",
"MR_10","Guidimaka",
"MR_11","Tiris Zemmour",
"MR_12","Inchiri",
"MS_01","Saint Anthony",
"MS_02","Saint Georges",
"MS_03","Saint Peter",
"MU_12","Black River",
"MU_13","Flacq",
"MU_14","Grand Port",
"MU_15","Moka",
"MU_16","Pamplemousses",
"MU_17","Plaines Wilhems",
"MU_18","Port Louis",
"MU_19","Riviere du Rempart",
"MU_20","Savanne",
"MU_21","Agalega Islands",
"MU_22","Cargados Carajos",
"MU_23","Rodrigues",
"MV_01","Seenu",
"MV_02","Aliff",
"MV_03","Laviyani",
"MV_04","Waavu",
"MV_05","Laamu",
"MV_07","Haa Aliff",
"MV_08","Thaa",
"MV_12","Meemu",
"MV_13","Raa",
"MV_14","Faafu",
"MV_17","Daalu",
"MV_20","Baa",
"MV_23","Haa Daalu",
"MV_24","Shaviyani",
"MV_25","Noonu",
"MV_26","Kaafu",
"MV_27","Gaafu Aliff",
"MV_28","Gaafu Daalu",
"MV_29","Naviyani",
"MW_02","Chikwawa",
"MW_03","Chiradzulu",
"MW_04","Chitipa",
"MW_05","Thyolo",
"MW_06","Dedza",
"MW_07","Dowa",
"MW_08","Karonga",
"MW_09","Kasungu",
"MW_11","Lilongwe",
"MW_12","Mangochi",
"MW_13","Mchinji",
"MW_15","Mzimba",
"MW_16","Ntcheu",
"MW_17","Nkhata Bay",
"MW_18","Nkhotakota",
"MW_19","Nsanje",
"MW_20","Ntchisi",
"MW_21","Rumphi",
"MW_22","Salima",
"MW_23","Zomba",
"MW_24","Blantyre",
"MW_25","Mwanza",
"MW_26","Balaka",
"MW_27","Likoma",
"MW_28","Machinga",
"MW_29","Mulanje",
"MW_30","Phalombe",
"MX_01","Aguascalientes",
"MX_02","Baja California",
"MX_03","Baja California Sur",
"MX_04","Campeche",
"MX_05","Chiapas",
"MX_06","Chihuahua",
"MX_07","Coahuila de Zaragoza",
"MX_08","Colima",
"MX_09","Distrito Federal",
"MX_10","Durango",
"MX_11","Guanajuato",
"MX_12","Guerrero",
"MX_13","Hidalgo",
"MX_14","Jalisco",
"MX_15","Mexico",
"MX_16","Michoacan de Ocampo",
"MX_17","Morelos",
"MX_18","Nayarit",
"MX_19","Nuevo Leon",
"MX_20","Oaxaca",
"MX_21","Puebla",
"MX_22","Queretaro de Arteaga",
"MX_23","Quintana Roo",
"MX_24","San Luis Potosi",
"MX_25","Sinaloa",
"MX_26","Sonora",
"MX_27","Tabasco",
"MX_28","Tamaulipas",
"MX_29","Tlaxcala",
"MX_30","Veracruz-Llave",
"MX_31","Yucatan",
"MX_32","Zacatecas",
"MY_01","Johor",
"MY_02","Kedah",
"MY_03","Kelantan",
"MY_04","Melaka",
"MY_05","Negeri Sembilan",
"MY_06","Pahang",
"MY_07","Perak",
"MY_08","Perlis",
"MY_09","Pulau Pinang",
"MY_11","Sarawak",
"MY_12","Selangor",
"MY_13","Terengganu",
"MY_14","Wilayah Persekutuan",
"MY_15","Labuan",
"MY_16","Sabah",
"MZ_01","Cabo Delgado",
"MZ_02","Gaza",
"MZ_03","Inhambane",
"MZ_04","Maputo",
"MZ_05","Sofala",
"MZ_06","Nampula",
"MZ_07","Niassa",
"MZ_08","Tete",
"MZ_09","Zambezia",
"MZ_10","Manica",
"NA_01","Bethanien",
"NA_02","Caprivi Oos",
"NA_03","Boesmanland",
"NA_04","Gobabis",
"NA_05","Grootfontein",
"NA_06","Kaokoland",
"NA_07","Karibib",
"NA_08","Keetmanshoop",
"NA_09","Luderitz",
"NA_10","Maltahohe",
"NA_11","Okahandja",
"NA_12","Omaruru",
"NA_13","Otjiwarongo",
"NA_14","Outjo",
"NA_15","Owambo",
"NA_16","Rehoboth",
"NA_17","Swakopmund",
"NA_18","Tsumeb",
"NA_20","Karasburg",
"NA_21","Windhoek",
"NA_22","Damaraland",
"NA_23","Hereroland Oos",
"NA_24","Hereroland Wes",
"NA_25","Kavango",
"NA_26","Mariental",
"NA_27","Namaland",
"NE_01","Agadez",
"NE_02","Diffa",
"NE_03","Dosso",
"NE_04","Maradi",
"NE_05","Niamey",
"NE_06","Tahoua",
"NE_07","Zinder",
"NG_05","Lagos",
"NG_11","Abuja Capital Territory",
"NG_16","Ogun",
"NG_21","Akwa Ibom",
"NG_22","Cross River",
"NG_23","Kaduna",
"NG_24","Katsina",
"NG_25","Anambra",
"NG_26","Benue",
"NG_27","Borno",
"NG_28","Imo",
"NG_29","Kano",
"NG_30","Kwara",
"NG_31","Niger",
"NG_32","Oyo",
"NG_35","Adamawa",
"NG_36","Delta",
"NG_37","Edo",
"NG_39","Jigawa",
"NG_40","Kebbi",
"NG_41","Kogi",
"NG_42","Osun",
"NG_43","Taraba",
"NG_44","Yobe",
"NG_45","Abia",
"NG_46","Bauchi",
"NG_47","Enugu",
"NG_48","Ondo",
"NG_49","Plateau",
"NG_50","Rivers",
"NG_51","Sokoto",
"NG_52","Bayelsa",
"NG_53","Ebonyi",
"NG_54","Ekiti",
"NG_55","Gombe",
"NG_56","Nassarawa",
"NG_57","Zamfara",
"NI_01","Boaco",
"NI_02","Carazo",
"NI_03","Chinandega",
"NI_04","Chontales",
"NI_05","Esteli",
"NI_06","Granada",
"NI_07","Jinotega",
"NI_08","Leon",
"NI_09","Madriz",
"NI_10","Managua",
"NI_11","Masaya",
"NI_12","Matagalpa",
"NI_13","Nueva Segovia",
"NI_14","Rio San Juan",
"NI_15","Rivas",
"NI_16","Zelaya",
"NL_01","Drenthe",
"NL_02","Friesland",
"NL_03","Gelderland",
"NL_04","Groningen",
"NL_05","Limburg",
"NL_06","Noord-Brabant",
"NL_07","Noord-Holland",
"NL_08","Overijssel",
"NL_09","Utrecht",
"NL_10","Zeeland",
"NL_11","Zuid-Holland",
"NL_12","Dronten",
"NL_13","Zuidelijke IJsselmeerpolders",
"NL_14","Lelystad",
"NL_15","Overijssel",
"NL_16","Flevoland",
"NO_01","Akershus",
"NO_02","Aust-Agder",
"NO_04","Buskerud",
"NO_05","Finnmark",
"NO_06","Hedmark",
"NO_07","Hordaland",
"NO_08","More og Romsdal",
"NO_09","Nordland",
"NO_10","Nord-Trondelag",
"NO_11","Oppland",
"NO_12","Oslo",
"NO_13","Ostfold",
"NO_14","Rogaland",
"NO_15","Sogn og Fjordane",
"NO_16","Sor-Trondelag",
"NO_17","Telemark",
"NO_18","Troms",
"NO_19","Vest-Agder",
"NO_20","Vestfold",
"NP_01","Bagmati",
"NP_02","Bheri",
"NP_03","Dhawalagiri",
"NP_04","Gandaki",
"NP_05","Janakpur",
"NP_06","Karnali",
"NP_07","Kosi",
"NP_08","Lumbini",
"NP_09","Mahakali",
"NP_10","Mechi",
"NP_11","Narayani",
"NP_12","Rapti",
"NP_13","Sagarmatha",
"NP_14","Seti",
"NR_01","Aiwo",
"NR_02","Anabar",
"NR_03","Anetan",
"NR_04","Anibare",
"NR_05","Baiti",
"NR_06","Boe",
"NR_07","Buada",
"NR_08","Denigomodu",
"NR_09","Ewa",
"NR_10","Ijuw",
"NR_11","Meneng",
"NR_12","Nibok",
"NR_13","Uaboe",
"NR_14","Yaren",
"NZ_01","Akaroa",
"NZ_03","Amuri",
"NZ_04","Ashburton",
"NZ_07","Bay of Islands",
"NZ_08","Bruce",
"NZ_09","Buller",
"NZ_10","Chatham Islands",
"NZ_11","Cheviot",
"NZ_12","Clifton",
"NZ_13","Clutha",
"NZ_14","Cook",
"NZ_16","Dannevirke",
"NZ_17","Egmont",
"NZ_18","Eketahuna",
"NZ_19","Ellesmere",
"NZ_20","Eltham",
"NZ_21","Eyre",
"NZ_22","Featherston",
"NZ_24","Franklin",
"NZ_26","Golden Bay",
"NZ_27","Great Barrier Island",
"NZ_28","Grey",
"NZ_29","Hauraki Plains",
"NZ_30","Hawera",
"NZ_31","Hawke's Bay",
"NZ_32","Heathcote",
"NZ_33","Hobson",
"NZ_34","Hokianga",
"NZ_35","Horowhenua",
"NZ_36","Hutt",
"NZ_37","Inangahua",
"NZ_38","Inglewood",
"NZ_39","Kaikoura",
"NZ_40","Kairanga",
"NZ_41","Kiwitea",
"NZ_43","Lake",
"NZ_45","Mackenzie",
"NZ_46","Malvern",
"NZ_47","Manawatu",
"NZ_48","Mangonui",
"NZ_49","Maniototo",
"NZ_50","Marlborough",
"NZ_51","Masterton",
"NZ_52","Matamata",
"NZ_53","Mount Herbert",
"NZ_54","Ohinemuri",
"NZ_55","Opotiki",
"NZ_56","Oroua",
"NZ_57","Otamatea",
"NZ_58","Otorohanga",
"NZ_59","Oxford",
"NZ_60","Pahiatua",
"NZ_61","Paparua",
"NZ_63","Patea",
"NZ_65","Piako",
"NZ_66","Pohangina",
"NZ_67","Raglan",
"NZ_68","Rangiora",
"NZ_69","Rangitikei",
"NZ_70","Rodney",
"NZ_71","Rotorua",
"NZ_72","Southland",
"NZ_73","Stewart Island",
"NZ_74","Stratford",
"NZ_76","Taranaki",
"NZ_77","Taumarunui",
"NZ_78","Taupo",
"NZ_79","Tauranga",
"NZ_81","Tuapeka",
"NZ_82","Vincent",
"NZ_83","Waiapu",
"NZ_84","Waihemo",
"NZ_85","Waikato",
"NZ_86","Waikohu",
"NZ_88","Waimairi",
"NZ_89","Waimarino",
"NZ_90","Waimate",
"NZ_91","Waimate West",
"NZ_92","Waimea",
"NZ_93","Waipa",
"NZ_95","Waipawa",
"NZ_96","Waipukurau",
"NZ_97","Wairarapa South",
"NZ_98","Wairewa",
"NZ_99","Wairoa",
"NZ_A1","Whangarei",
"NZ_A2","Whangaroa",
"NZ_A3","Woodville",
"NZ_A4","Waitaki",
"NZ_A6","Waitomo",
"NZ_A8","Waitotara",
"NZ_B2","Wanganui",
"NZ_B3","Westland",
"NZ_B4","Whakatane",
"NZ_D4","Hurunui",
"NZ_D5","Silverpeaks",
"NZ_D6","Strathallan",
"NZ_D8","Waiheke",
"NZ_D9","Hikurangi",
"NZ_E1","Manaia",
"NZ_E2","Runanga",
"NZ_E3","Saint Kilda",
"NZ_E4","Thames-Coromandel",
"NZ_E5","Waverley",
"NZ_E6","Wallace",
"OM_01","Ad Dakhiliyah",
"OM_02","Al Batinah",
"OM_03","Al Wusta",
"OM_04","Ash Sharqiyah",
"OM_05","Az Zahirah",
"OM_06","Masqat",
"OM_07","Musandam",
"OM_08","Zufar",
"PA_01","Bocas del Toro",
"PA_02","Chiriqui",
"PA_03","Cocle",
"PA_04","Colon",
"PA_05","Darien",
"PA_06","Herrera",
"PA_07","Los Santos",
"PA_08","Panama",
"PA_09","San Blas",
"PA_10","Veraguas",
"PE_01","Amazonas",
"PE_02","Ancash",
"PE_03","Apurimac",
"PE_04","Arequipa",
"PE_05","Ayacucho",
"PE_06","Cajamarca",
"PE_07","Callao",
"PE_08","Cusco",
"PE_09","Huancavelica",
"PE_10","Huanuco",
"PE_11","Ica",
"PE_12","Junin",
"PE_13","La Libertad",
"PE_14","Lambayeque",
"PE_15","Lima",
"PE_16","Loreto",
"PE_17","Madre de Dios",
"PE_18","Moquegua",
"PE_19","Pasco",
"PE_20","Piura",
"PE_21","Puno",
"PE_22","San Martin",
"PE_23","Tacna",
"PE_24","Tumbes",
"PE_25","Ucayali",
"PG_01","Central",
"PG_02","Gulf",
"PG_03","Milne Bay",
"PG_04","Northern",
"PG_05","Southern Highlands",
"PG_06","Western",
"PG_07","North Solomons",
"PG_08","Chimbu",
"PG_09","Eastern Highlands",
"PG_10","East New Britain",
"PG_11","East Sepik",
"PG_12","Madang",
"PG_13","Manus",
"PG_14","Morobe",
"PG_15","New Ireland",
"PG_16","Western Highlands",
"PG_17","West New Britain",
"PG_18","Sandaun",
"PG_19","Enga",
"PG_20","National Capital",
"PH_01","Abra",
"PH_02","Agusan del Norte",
"PH_03","Agusan del Sur",
"PH_04","Aklan",
"PH_05","Albay",
"PH_06","Antique",
"PH_07","Bataan",
"PH_08","Batanes",
"PH_09","Batangas",
"PH_10","Benguet",
"PH_11","Bohol",
"PH_12","Bukidnon",
"PH_13","Bulacan",
"PH_14","Cagayan",
"PH_15","Camarines Norte",
"PH_16","Camarines Sur",
"PH_17","Camiguin",
"PH_18","Capiz",
"PH_19","Catanduanes",
"PH_20","Cavite",
"PH_21","Cebu",
"PH_22","Basilan",
"PH_23","Eastern Samar",
"PH_24","Davao",
"PH_25","Davao del Sur",
"PH_26","Davao Oriental",
"PH_27","Ifugao",
"PH_28","Ilocos Norte",
"PH_29","Ilocos Sur",
"PH_30","Iloilo",
"PH_31","Isabela",
"PH_32","Kalinga-Apayao",
"PH_33","Laguna",
"PH_34","Lanao del Norte",
"PH_35","Lanao del Sur",
"PH_36","La Union",
"PH_37","Leyte",
"PH_38","Marinduque",
"PH_39","Masbate",
"PH_40","Mindoro Occidental",
"PH_41","Mindoro Oriental",
"PH_42","Misamis Occidental",
"PH_43","Misamis Oriental",
"PH_44","Mountain",
"PH_46","Negros Oriental",
"PH_47","Nueva Ecija",
"PH_48","Nueva Vizcaya",
"PH_49","Palawan",
"PH_50","Pampanga",
"PH_51","Pangasinan",
"PH_53","Rizal",
"PH_54","Romblon",
"PH_55","Samar",
"PH_56","Maguindanao",
"PH_57","North Cotabato",
"PH_58","Sorsogon",
"PH_59","Southern Leyte",
"PH_60","Sulu",
"PH_61","Surigao del Norte",
"PH_62","Surigao del Sur",
"PH_63","Tarlac",
"PH_64","Zambales",
"PH_65","Zamboanga del Norte",
"PH_66","Zamboanga del Sur",
"PH_67","Northern Samar",
"PH_68","Quirino",
"PH_69","Siquijor",
"PH_70","South Cotabato",
"PH_71","Sultan Kudarat",
"PH_72","Tawitawi",
"PH_A1","Angeles",
"PH_A2","Bacolod",
"PH_A3","Bago",
"PH_A4","Baguio",
"PH_A5","Bais",
"PH_A6","Basilan City",
"PH_A7","Batangas City",
"PH_A8","Butuan",
"PH_A9","Cabanatuan",
"PH_B1","Cadiz",
"PH_B2","Cagayan de Oro",
"PH_B3","Calbayog",
"PH_B4","Caloocan",
"PH_B5","Canlaon",
"PH_B6","Cavite City",
"PH_B7","Cebu City",
"PH_B8","Cotabato",
"PH_B9","Dagupan",
"PH_C1","Danao",
"PH_C2","Dapitan",
"PH_C3","Davao City",
"PH_C4","Dipolog",
"PH_C5","Dumaguete",
"PH_C6","General Santos",
"PH_C7","Gingoog",
"PH_C8","Iligan",
"PH_C9","Iloilo City",
"PH_D1","Iriga",
"PH_D2","La Carlota",
"PH_D3","Laoag",
"PH_D4","Lapu-Lapu",
"PH_D5","Legaspi",
"PH_D6","Lipa",
"PH_D7","Lucena",
"PH_D8","Mandaue",
"PH_D9","Manila",
"PH_E1","Marawi",
"PH_E2","Naga",
"PH_E3","Olongapo",
"PH_E4","Ormoc",
"PH_E5","Oroquieta",
"PH_E6","Ozamis",
"PH_E7","Pagadian",
"PH_E8","Palayan",
"PH_E9","Pasay",
"PH_F1","Puerto Princesa",
"PH_F2","Quezon City",
"PH_F3","Roxas",
"PH_F4","San Carlos",
"PH_F5","San Carlos",
"PH_F6","San Jose",
"PH_F7","San Pablo",
"PH_F8","Silay",
"PH_F9","Surigao",
"PH_G1","Tacloban",
"PH_G2","Tagaytay",
"PH_G3","Tagbilaran",
"PH_G4","Tangub",
"PH_G5","Toledo",
"PH_G6","Trece Martires",
"PH_G7","Zamboanga",
"PH_G8","Aurora",
"PH_H2","Quezon",
"PH_H3","Negros Occidental",
"PK_01","Federally Administered Tribal Areas",
"PK_02","Balochistan",
"PK_03","North-West Frontier",
"PK_04","Punjab",
"PK_05","Sindh",
"PK_06","Azad Kashmir",
"PK_07","Northern Areas",
"PK_08","Islamabad",
"PL_23","Biala Podlaska",
"PL_24","Bialystok",
"PL_25","Bielsko",
"PL_26","Bydgoszcz",
"PL_27","Chelm",
"PL_28","Ciechanow",
"PL_29","Czestochowa",
"PL_30","Elblag",
"PL_31","Gdansk",
"PL_32","Gorzow",
"PL_33","Jelenia Gora",
"PL_34","Kalisz",
"PL_35","Katowice",
"PL_36","Kielce",
"PL_37","Konin",
"PL_38","Koszalin",
"PL_39","Krakow",
"PL_40","Krosno",
"PL_41","Legnica",
"PL_42","Leszno",
"PL_43","Lodz",
"PL_44","Lomza",
"PL_45","Lublin",
"PL_46","Nowy Sacz",
"PL_47","Olsztyn",
"PL_48","Opole",
"PL_49","Ostroleka",
"PL_50","Pila",
"PL_51","Piotrkow",
"PL_52","Plock",
"PL_53","Poznan",
"PL_54","Przemysl",
"PL_55","Radom",
"PL_56","Rzeszow",
"PL_57","Siedlce",
"PL_58","Sieradz",
"PL_59","Skierniewice",
"PL_60","Slupsk",
"PL_61","Suwalki",
"PL_62","Szczecin",
"PL_63","Tarnobrzeg",
"PL_64","Tarnow",
"PL_65","Torun",
"PL_66","Walbrzych",
"PL_67","Warszawa",
"PL_68","Wloclawek",
"PL_69","Wroclaw",
"PL_70","Zamosc",
"PL_71","Zielona Gora",
"PL_72","Dolnoslaskie",
"PL_73","Kujawsko-Pomorskie",
"PL_74","Lodzkie",
"PL_75","Lubelskie",
"PL_76","Lubuskie",
"PL_77","Malopolskie",
"PL_78","Mazowieckie",
"PL_79","Opolskie",
"PL_80","Podkarpackie",
"PL_81","Podlaskie",
"PL_82","Pomorskie",
"PL_83","Slaskie",
"PL_84","Swietokrzyskie",
"PL_85","Warminsko-Mazurskie",
"PL_86","Wielkopolskie",
"PL_87","Zachodniopomorskie",
"PT_02","Aveiro",
"PT_03","Beja",
"PT_04","Braga",
"PT_05","Braganca",
"PT_06","Castelo Branco",
"PT_07","Coimbra",
"PT_08","Evora",
"PT_09","Faro",
"PT_10","Madeira",
"PT_11","Guarda",
"PT_13","Leiria",
"PT_14","Lisboa",
"PT_16","Portalegre",
"PT_17","Porto",
"PT_18","Santarem",
"PT_19","Setubal",
"PT_20","Viana do Castelo",
"PT_21","Vila Real",
"PT_22","Viseu",
"PT_23","Azores",
"PY_01","Alto Parana",
"PY_02","Amambay",
"PY_03","Boqueron",
"PY_04","Caaguazu",
"PY_05","Caazapa",
"PY_06","Central",
"PY_07","Concepcion",
"PY_08","Cordillera",
"PY_10","Guaira",
"PY_11","Itapua",
"PY_12","Misiones",
"PY_13","Neembucu",
"PY_15","Paraguari",
"PY_16","Presidente Hayes",
"PY_17","San Pedro",
"PY_18","Alto Paraguay",
"PY_19","Canindeyu",
"PY_20","Chaco",
"PY_21","Nueva Asuncion",
"QA_01","Ad Dawhah",
"QA_02","Al Ghuwariyah",
"QA_03","Al Jumaliyah",
"QA_04","Al Khawr",
"QA_06","Ar Rayyan",
"QA_08","Madinat ach Shamal",
"QA_09","Umm Salal",
"QA_10","Al Wakrah",
"QA_11","Jariyan al Batnah",
"QA_12","Umm Sa'id",
"RO_01","Alba",
"RO_02","Arad",
"RO_03","Arges",
"RO_04","Bacau",
"RO_05","Bihor",
"RO_06","Bistrita-Nasaud",
"RO_07","Botosani",
"RO_08","Braila",
"RO_09","Brasov",
"RO_10","Bucuresti",
"RO_11","Buzau",
"RO_12","Caras-Severin",
"RO_13","Cluj",
"RO_14","Constanta",
"RO_15","Covasna",
"RO_16","Dambovita",
"RO_17","Dolj",
"RO_18","Galati",
"RO_19","Gorj",
"RO_20","Harghita",
"RO_21","Hunedoara",
"RO_22","Ialomita",
"RO_23","Iasi",
"RO_25","Maramures",
"RO_26","Mehedinti",
"RO_27","Mures",
"RO_28","Neamt",
"RO_29","Olt",
"RO_30","Prahova",
"RO_31","Salaj",
"RO_32","Satu Mare",
"RO_33","Sibiu",
"RO_34","Suceava",
"RO_35","Teleorman",
"RO_36","Timis",
"RO_37","Tulcea",
"RO_38","Vaslui",
"RO_39","Valcea",
"RO_40","Vrancea",
"RO_41","Calarasi",
"RO_42","Giurgiu",
"RO_43","Ilfov",
"RU_01","Adygey",
"RU_02","Aga Buryat",
"RU_03","Gorno-Altay",
"RU_04","Altay",
"RU_05","Amur",
"RU_06","Arkhangel'sk",
"RU_07","Astrakhan'",
"RU_08","Bashkortostan",
"RU_09","Belgorod",
"RU_10","Bryansk",
"RU_11","Buryat",
"RU_12","Chechnya",
"RU_13","Chelyabinsk",
"RU_14","Chita",
"RU_15","Chukot",
"RU_16","Chuvash",
"RU_17","Dagestan",
"RU_18","Evenk",
"RU_19","Ingush",
"RU_20","Irkutsk",
"RU_21","Ivanovo",
"RU_22","Kabardin-Balkar",
"RU_23","Kaliningrad",
"RU_24","Kalmyk",
"RU_25","Kaluga",
"RU_26","Kamchatka",
"RU_27","Karachay-Cherkess",
"RU_28","Karelia",
"RU_29","Kemerovo",
"RU_30","Khabarovsk",
"RU_31","Khakass",
"RU_32","Khanty-Mansiy",
"RU_33","Kirov",
"RU_34","Komi",
"RU_35","Komi-Permyak",
"RU_36","Koryak",
"RU_37","Kostroma",
"RU_38","Krasnodar",
"RU_39","Krasnoyarsk",
"RU_40","Kurgan",
"RU_41","Kursk",
"RU_42","Leningrad",
"RU_43","Lipetsk",
"RU_44","Magadan",
"RU_45","Mariy-El",
"RU_46","Mordovia",
"RU_47","Moskva",
"RU_48","Moscow City",
"RU_49","Murmansk",
"RU_50","Nenets",
"RU_51","Nizhegorod",
"RU_52","Novgorod",
"RU_53","Novosibirsk",
"RU_54","Omsk",
"RU_55","Orenburg",
"RU_56","Orel",
"RU_57","Penza",
"RU_58","Perm'",
"RU_59","Primor'ye",
"RU_60","Pskov",
"RU_61","Rostov",
"RU_62","Ryazan'",
"RU_63","Sakha",
"RU_64","Sakhalin",
"RU_65","Samara",
"RU_66","Saint Petersburg City",
"RU_67","Saratov",
"RU_68","North Ossetia",
"RU_69","Smolensk",
"RU_70","Stavropol'",
"RU_71","Sverdlovsk",
"RU_72","Tambov",
"RU_73","Tatarstan",
"RU_74","Taymyr",
"RU_75","Tomsk",
"RU_76","Tula",
"RU_77","Tver'",
"RU_78","Tyumen'",
"RU_79","Tuva",
"RU_80","Udmurt",
"RU_81","Ul'yanovsk",
"RU_82","Ust-Orda Buryat",
"RU_83","Vladimir",
"RU_84","Volgograd",
"RU_85","Vologda",
"RU_86","Voronezh",
"RU_87","Yamal-Nenets",
"RU_88","Yaroslavl'",
"RU_89","Yevrey",
"RW_01","Butare",
"RW_02","Byumba",
"RW_03","Cyangugu",
"RW_04","Gikongoro",
"RW_05","Gisenyi",
"RW_06","Gitarama",
"RW_07","Kibungo",
"RW_08","Kibuye",
"RW_09","Kigali",
"RW_10","Ruhengeri",
"SA_02","Al Bahah",
"SA_03","Al Jawf",
"SA_05","Al Madinah",
"SA_06","Ash Sharqiyah",
"SA_08","Al Qasim",
"SA_09","Al Qurayyat",
"SA_10","Ar Riyad",
"SA_13","Ha'il",
"SA_14","Makkah",
"SA_15","Al Hudud ash Shamaliyah",
"SA_16","Najran",
"SA_17","Jizan",
"SA_19","Tabuk",
"SB_03","Malaita",
"SB_04","Western",
"SB_05","Central",
"SB_06","Guadalcanal",
"SB_07","Isabel",
"SB_08","Makira",
"SB_09","Temotu",
"SC_01","Anse aux Pins",
"SC_02","Anse Boileau",
"SC_03","Anse Etoile",
"SC_04","Anse Louis",
"SC_05","Anse Royale",
"SC_06","Baie Lazare",
"SC_07","Baie Sainte Anne",
"SC_08","Beau Vallon",
"SC_09","Bel Air",
"SC_10","Bel Ombre",
"SC_11","Cascade",
"SC_12","Glacis",
"SC_13","Grand' Anse",
"SC_14","Grand' Anse",
"SC_15","La Digue",
"SC_16","La Riviere Anglaise",
"SC_17","Mont Buxton",
"SC_18","Mont Fleuri",
"SC_19","Plaisance",
"SC_20","Pointe La Rue",
"SC_21","Port Glaud",
"SC_22","Saint Louis",
"SC_23","Takamaka",
"SD_27","Al Wusta",
"SD_28","Al Istiwa'iyah",
"SD_29","Al Khartum",
"SD_30","Ash Shamaliyah",
"SD_31","Ash Sharqiyah",
"SD_32","Bahr al Ghazal",
"SD_33","Darfur",
"SD_34","Kurdufan",
"SE_01","Alvsborgs Lan",
"SE_02","Blekinge Lan",
"SE_03","Gavleborgs Lan",
"SE_04","Goteborgs och Bohus Lan",
"SE_05","Gotlands Lan",
"SE_06","Hallands Lan",
"SE_07","Jamtlands Lan",
"SE_08","Jonkopings Lan",
"SE_09","Kalmar Lan",
"SE_10","Dalarnas Lan",
"SE_11","Kristianstads Lan",
"SE_12","Kronobergs Lan",
"SE_13","Malmohus Lan",
"SE_14","Norrbottens Lan",
"SE_15","Orebro Lan",
"SE_16","Ostergotlands Lan",
"SE_17","Skaraborgs Lan",
"SE_18","Sodermanlands Lan",
"SE_21","Uppsala Lan",
"SE_22","Varmlands Lan",
"SE_23","Vasterbottens Lan",
"SE_24","Vasternorrlands Lan",
"SE_25","Vastmanlands Lan",
"SE_26","Stockholms Lan",
"SE_27","Skane Lan",
"SE_28","Vastra Gotaland",
"SH_01","Ascension",
"SH_02","Saint Helena",
"SH_03","Tristan da Cunha",
"SI_01","Ajdovscina",
"SI_02","Beltinci",
"SI_03","Bled",
"SI_04","Bohinj",
"SI_05","Borovnica",
"SI_06","Bovec",
"SI_07","Brda",
"SI_08","Brezice",
"SI_09","Brezovica",
"SI_11","Celje",
"SI_12","Cerklje na Gorenjskem",
"SI_13","Cerknica",
"SI_14","Cerkno",
"SI_15","Crensovci",
"SI_16","Crna na Koroskem",
"SI_17","Crnomelj",
"SI_19","Divaca",
"SI_20","Dobrepolje",
"SI_22","Dol pri Ljubljani",
"SI_24","Dornava",
"SI_25","Dravograd",
"SI_26","Duplek",
"SI_27","Gorenja Vas-Poljane",
"SI_28","Gorisnica",
"SI_29","Gornja Radgona",
"SI_30","Gornji Grad",
"SI_31","Gornji Petrovci",
"SI_32","Grosuplje",
"SI_34","Hrastnik",
"SI_35","Hrpelje-Kozina",
"SI_36","Idrija",
"SI_37","Ig",
"SI_38","Ilirska Bistrica",
"SI_39","Ivancna Gorica",
"SI_40","Izola-Isola",
"SI_42","Jursinci",
"SI_44","Kanal",
"SI_45","Kidricevo",
"SI_46","Kobarid",
"SI_47","Kobilje",
"SI_49","Komen",
"SI_50","Koper-Capodistria",
"SI_51","Kozje",
"SI_52","Kranj",
"SI_53","Kranjska Gora",
"SI_54","Krsko",
"SI_55","Kungota",
"SI_57","Lasko",
"SI_61","Ljubljana",
"SI_62","Ljubno",
"SI_64","Logatec",
"SI_66","Loski Potok",
"SI_68","Lukovica",
"SI_71","Medvode",
"SI_72","Menges",
"SI_73","Metlika",
"SI_74","Mezica",
"SI_76","Mislinja",
"SI_77","Moravce",
"SI_78","Moravske Toplice",
"SI_79","Mozirje",
"SI_80","Murska Sobota",
"SI_81","Muta",
"SI_82","Naklo",
"SI_83","Nazarje",
"SI_84","Nova Gorica",
"SI_86","Odranci",
"SI_87","Ormoz",
"SI_88","Osilnica",
"SI_89","Pesnica",
"SI_91","Pivka",
"SI_92","Podcetrtek",
"SI_94","Postojna",
"SI_97","Puconci",
"SI_98","Racam",
"SI_99","Radece",
"SI_A1","Radenci",
"SI_A2","Radlje ob Dravi",
"SI_A3","Radovljica",
"SI_A6","Rogasovci",
"SI_A7","Rogaska Slatina",
"SI_A8","Rogatec",
"SI_B1","Semic",
"SI_B2","Sencur",
"SI_B3","Sentilj",
"SI_B4","Sentjernej",
"SI_B6","Sevnica",
"SI_B7","Sezana",
"SI_B8","Skocjan",
"SI_B9","Skofja Loka",
"SI_C1","Skofljica",
"SI_C2","Slovenj Gradec",
"SI_C4","Slovenske Konjice",
"SI_C5","Smarje pri Jelsah",
"SI_C6","Smartno ob Paki",
"SI_C7","Sostanj",
"SI_C8","Starse",
"SI_C9","Store",
"SI_D1","Sveti Jurij",
"SI_D2","Tolmin",
"SI_D3","Trbovlje",
"SI_D4","Trebnje",
"SI_D5","Trzic",
"SI_D6","Turnisce",
"SI_D7","Velenje",
"SI_D8","Velike Lasce",
"SI_E1","Vipava",
"SI_E2","Vitanje",
"SI_E3","Vodice",
"SI_E5","Vrhnika",
"SI_E6","Vuzenica",
"SI_E7","Zagorje ob Savi",
"SI_E9","Zavrc",
"SI_F1","Zelezniki",
"SI_F2","Ziri",
"SI_F3","Zrece",
"SI_G4","Dobrova-Horjul-Polhov Gradec",
"SI_G7","Domzale",
"SI_H4","Jesenice",
"SI_H6","Kamnik",
"SI_H7","Kocevje",
"SI_I2","Kuzma",
"SI_I3","Lenart",
"SI_I5","Litija",
"SI_I6","Ljutomer",
"SI_I7","Loska Dolina",
"SI_I9","Luce",
"SI_J1","Majsperk",
"SI_J2","Maribor",
"SI_J5","Miren-Kostanjevica",
"SI_J7","Novo Mesto",
"SI_J9","Piran",
"SI_K5","Preddvor",
"SI_K7","Ptuj",
"SI_L1","Ribnica",
"SI_L3","Ruse",
"SI_L7","Sentjur pri Celju",
"SI_L8","Slovenska Bistrica",
"SI_N2","Videm",
"SI_N3","Vojnik",
"SI_N5","Zalec",
"SK_01","Banska Bystrica",
"SK_02","Bratislava",
"SK_03","Kosice",
"SK_04","Nitra",
"SK_05","Presov",
"SK_06","Trencin",
"SK_07","Trnava",
"SK_08","Zilina",
"SL_01","Eastern",
"SL_02","Northern",
"SL_03","Southern",
"SL_04","Western Area",
"SM_01","Acquaviva",
"SM_02","Chiesanuova",
"SM_03","Domagnano",
"SM_04","Faetano",
"SM_05","Fiorentino",
"SM_06","Borgo Maggiore",
"SM_07","San Marino",
"SM_08","Monte Giardino",
"SM_09","Serravalle",
"SN_01","Dakar",
"SN_03","Diourbel",
"SN_04","Saint-Louis",
"SN_05","Tambacounda",
"SN_07","Thies",
"SN_08","Louga",
"SN_09","Fatick",
"SN_10","Kaolack",
"SN_11","Kolda",
"SN_12","Ziguinchor",
"SO_01","Bakool",
"SO_02","Banaadir",
"SO_03","Bari",
"SO_04","Bay",
"SO_05","Galguduud",
"SO_06","Gedo",
"SO_07","Hiiraan",
"SO_08","Jubbada Dhexe",
"SO_09","Jubbada Hoose",
"SO_10","Mudug",
"SO_11","Nugaal",
"SO_12","Sanaag",
"SO_13","Shabeellaha Dhexe",
"SO_14","Shabeellaha Hoose",
"SO_15","Togdheer",
"SO_16","Woqooyi Galbeed",
"SR_10","Brokopondo",
"SR_11","Commewijne",
"SR_12","Coronie",
"SR_13","Marowijne",
"SR_14","Nickerie",
"SR_15","Para",
"SR_16","Paramaribo",
"SR_17","Saramacca",
"SR_18","Sipaliwini",
"SR_19","Wanica",
"ST_01","Principe",
"ST_02","Sao Tome",
"SV_01","Ahuachapan",
"SV_02","Cabanas",
"SV_03","Chalatenango",
"SV_04","Cuscatlan",
"SV_05","La Libertad",
"SV_06","La Paz",
"SV_07","La Union",
"SV_08","Morazan",
"SV_09","San Miguel",
"SV_10","San Salvador",
"SV_11","Santa Ana",
"SV_12","San Vicente",
"SV_13","Sonsonate",
"SV_14","Usulutan",
"SY_01","Al Hasakah",
"SY_02","Al Ladhiqiyah",
"SY_03","Al Qunaytirah",
"SY_04","Ar Raqqah",
"SY_05","As Suwayda'",
"SY_06","Dar",
"SY_07","Dayr az Zawr",
"SY_08","Rif Dimashq",
"SY_09","Halab",
"SY_10","Hamah",
"SY_11","Hims",
"SY_12","Idlib",
"SY_13","Dimashq",
"SY_14","Tartus",
"SZ_01","Hhohho",
"SZ_02","Lubombo",
"SZ_03","Manzini",
"SZ_04","Shiselweni",
"SZ_05","Praslin",
"TD_01","Batha",
"TD_02","Biltine",
"TD_03","Borkou-Ennedi-Tibesti",
"TD_04","Chari-Baguirmi",
"TD_05","Guera",
"TD_06","Kanem",
"TD_07","Lac",
"TD_08","Logone Occidental",
"TD_09","Logone Oriental",
"TD_10","Mayo-Kebbi",
"TD_11","Moyen-Chari",
"TD_12","Ouaddai",
"TD_13","Salamat",
"TD_14","Tandjile",
"TG_01","Amlame",
"TG_02","Aneho",
"TG_03","Atakpame",
"TG_04","Bafilo",
"TG_05","Bassar",
"TG_06","Dapaong",
"TG_07","Kante",
"TG_08","Klouto",
"TG_09","Lama-Kara",
"TG_10","Lome",
"TG_11","Mango",
"TG_12","Niamtougou",
"TG_13","Notse",
"TG_14","Kpagouda",
"TG_15","Badou",
"TG_16","Sotouboua",
"TG_17","Tabligbo",
"TG_18","Tsevie",
"TG_19","Tchamba",
"TG_20","Tchaoudjo",
"TG_21","Vogan",
"TH_01","Mae Hong Son",
"TH_02","Chiang Mai",
"TH_03","Chiang Rai",
"TH_04","Nan",
"TH_05","Lamphun",
"TH_06","Lampang",
"TH_07","Phrae",
"TH_08","Tak",
"TH_09","Sukhothai",
"TH_10","Uttaradit",
"TH_11","Kamphaeng Phet",
"TH_12","Phitsanulok",
"TH_13","Phichit",
"TH_14","Phetchabun",
"TH_15","Uthai Thani",
"TH_16","Nakhon Sawan",
"TH_17","Nong Khai",
"TH_18","Loei",
"TH_19","Udon Thani",
"TH_20","Sakon Nakhon",
"TH_21","Nakhon Phanom",
"TH_22","Khon Kaen",
"TH_23","Kalasin",
"TH_24","Maha Sarakham",
"TH_25","Roi Et",
"TH_26","Chaiyaphum",
"TH_27","Nakhon Ratchasima",
"TH_28","Buriram",
"TH_29","Surin",
"TH_30","Sisaket",
"TH_31","Narathiwat",
"TH_32","Chai Nat",
"TH_33","Sing Buri",
"TH_34","Lop Buri",
"TH_35","Ang Thong",
"TH_36","Phra Nakhon Si Ayutthaya",
"TH_37","Saraburi",
"TH_38","Nonthaburi",
"TH_39","Pathum Thani",
"TH_40","Krung Thep",
"TH_41","Phayao",
"TH_42","Samut Prakan",
"TH_43","Nakhon Nayok",
"TH_44","Chachoengsao",
"TH_45","Prachin Buri",
"TH_46","Chon Buri",
"TH_47","Rayong",
"TH_48","Chanthaburi",
"TH_49","Trat",
"TH_50","Kanchanaburi",
"TH_51","Suphan Buri",
"TH_52","Ratchaburi",
"TH_53","Nakhon Pathom",
"TH_54","Samut Songkhram",
"TH_55","Samut Sakhon",
"TH_56","Phetchaburi",
"TH_57","Prachuap Khiri Khan",
"TH_58","Chumphon",
"TH_59","Ranong",
"TH_60","Surat Thani",
"TH_61","Phangnga",
"TH_62","Phuket",
"TH_63","Krabi",
"TH_64","Nakhon Si Thammarat",
"TH_65","Trang",
"TH_66","Phatthalung",
"TH_67","Satun",
"TH_68","Songkhla",
"TH_69","Pattani",
"TH_70","Yala",
"TH_71","Ubon Ratchathani",
"TH_72","Yasothon",
"TJ_01","Kuhistoni Badakhshon",
"TJ_02","Khatlon",
"TJ_03","Sughd",
"TM_01","Ahal",
"TM_02","Balkan",
"TM_03","Dashoguz",
"TM_04","Lebap",
"TM_05","Mary",
"TN_02","Al Qasrayn",
"TN_03","Al Qayrawan",
"TN_06","Jundubah",
"TN_10","Qafsah",
"TN_14","Kef",
"TN_15","Al Mahdiyah",
"TN_16","Al Munastir",
"TN_17","Bajah",
"TN_18","Banzart",
"TN_19","Nabul",
"TN_22","Silyanah",
"TN_23","Susah",
"TN_27","Bin",
"TN_28","Madanin",
"TN_29","Qabis",
"TN_31","Qibili",
"TN_32","Safaqis",
"TN_33","Sidi Bu Zayd",
"TN_34","Tatawin",
"TN_35","Tawzar",
"TN_36","Tunis",
"TN_37","Zaghwan",
"TN_38","Ariana",
"TN_39","Manouba",
"TO_01","Ha",
"TO_02","Tongatapu",
"TO_03","Vava",
"TR_02","Adiyaman",
"TR_03","Afyon",
"TR_04","Agri",
"TR_05","Amasya",
"TR_07","Antalya",
"TR_08","Artvin",
"TR_09","Aydin",
"TR_10","Balikesir",
"TR_11","Bilecik",
"TR_12","Bingol",
"TR_13","Bitlis",
"TR_14","Bolu",
"TR_15","Burdur",
"TR_16","Bursa",
"TR_17","Canakkale",
"TR_19","Corum",
"TR_20","Denizli",
"TR_21","Diyarbakir",
"TR_22","Edirne",
"TR_23","Elazig",
"TR_24","Erzincan",
"TR_25","Erzurum",
"TR_26","Eskisehir",
"TR_28","Giresun",
"TR_31","Hatay",
"TR_32","Icel",
"TR_33","Isparta",
"TR_34","Istanbul",
"TR_35","Izmir",
"TR_37","Kastamonu",
"TR_38","Kayseri",
"TR_39","Kirklareli",
"TR_40","Kirsehir",
"TR_41","Kocaeli",
"TR_43","Kutahya",
"TR_44","Malatya",
"TR_45","Manisa",
"TR_46","Kahramanmaras",
"TR_48","Mugla",
"TR_49","Mus",
"TR_50","Nevsehir",
"TR_52","Ordu",
"TR_53","Rize",
"TR_54","Sakarya",
"TR_55","Samsun",
"TR_57","Sinop",
"TR_58","Sivas",
"TR_59","Tekirdag",
"TR_60","Tokat",
"TR_61","Trabzon",
"TR_62","Tunceli",
"TR_63","Sanliurfa",
"TR_64","Usak",
"TR_65","Van",
"TR_66","Yozgat",
"TR_68","Ankara",
"TR_69","Gumushane",
"TR_70","Hakkari",
"TR_71","Konya",
"TR_72","Mardin",
"TR_73","Nigde",
"TR_74","Siirt",
"TR_75","Aksaray",
"TR_76","Batman",
"TR_77","Bayburt",
"TR_78","Karaman",
"TR_79","Kirikkale",
"TR_80","Sirnak",
"TR_81","Adana",
"TR_82","Cankiri",
"TR_83","Gaziantep",
"TR_84","Kars",
"TR_85","Zonguldak",
"TR_86","Ardahan",
"TR_87","Bartin",
"TR_88","Igdir",
"TR_89","Karabuk",
"TR_90","Kilis",
"TR_91","Osmaniye",
"TR_92","Yalova",
"TR_93","Duzce",
"TT_01","Arima",
"TT_02","Caroni",
"TT_03","Mayaro",
"TT_04","Nariva",
"TT_05","Port-of-Spain",
"TT_06","Saint Andrew",
"TT_07","Saint David",
"TT_08","Saint George",
"TT_09","Saint Patrick",
"TT_10","San Fernando",
"TT_11","Tobago",
"TT_12","Victoria",
"TW_01","Fu-chien",
"TW_02","Kao-hsiung",
"TW_03","T'ai-pei",
"TW_04","T'ai-wan",
"TZ_01","Arusha",
"TZ_02","Pwani",
"TZ_03","Dodoma",
"TZ_04","Iringa",
"TZ_05","Kigoma",
"TZ_06","Kilimanjaro",
"TZ_07","Lindi",
"TZ_08","Mara",
"TZ_09","Mbeya",
"TZ_10","Morogoro",
"TZ_11","Mtwara",
"TZ_12","Mwanza",
"TZ_13","Pemba North",
"TZ_14","Ruvuma",
"TZ_15","Shinyanga",
"TZ_16","Singida",
"TZ_17","Tabora",
"TZ_18","Tanga",
"TZ_19","Kagera",
"TZ_20","Pemba South",
"TZ_21","Zanzibar Central",
"TZ_22","Zanzibar North",
"TZ_23","Dar es Salaam",
"TZ_24","Rukwa",
"TZ_25","Zanzibar Urban",
"UA_01","Cherkas'ka Oblast'",
"UA_02","Chernihivs'ka Oblast'",
"UA_03","Chernivets'ka Oblast'",
"UA_04","Dnipropetrovs'ka Oblast'",
"UA_05","Donets'ka Oblast'",
"UA_06","Ivano-Frankivs'ka Oblast'",
"UA_07","Kharkivs'ka Oblast'",
"UA_08","Khersons'ka Oblast'",
"UA_09","Khmel'nyts'ka Oblast'",
"UA_10","Kirovohrads'ka Oblast'",
"UA_11","Krym",
"UA_12","Kyyiv",
"UA_13","Kyyivs'ka Oblast'",
"UA_14","Luhans'ka Oblast'",
"UA_15","L'vivs'ka Oblast'",
"UA_16","Mykolayivs'ka Oblast'",
"UA_17","Odes'ka Oblast'",
"UA_18","Poltavs'ka Oblast'",
"UA_19","Rivnens'ka Oblast'",
"UA_20","Sevastopol'",
"UA_21","Sums'ka Oblast'",
"UA_22","Ternopil's'ka Oblast'",
"UA_23","Vinnyts'ka Oblast'",
"UA_24","Volyns'ka Oblast'",
"UA_25","Zakarpats'ka Oblast'",
"UA_26","Zaporiz'ka Oblast'",
"UA_27","Zhytomyrs'ka Oblast'",
"UG_05","Busoga",
"UG_08","Karamoja",
"UG_12","South Buganda",
"UG_18","Central",
"UG_20","Eastern",
"UG_21","Nile",
"UG_22","North Buganda",
"UG_23","Northern",
"UG_24","Southern",
"UG_25","Western",
"UG_65","Adjumani",
"UG_66","Bugiri",
"UG_67","Busia",
"UG_69","Katakwi",
"UG_73","Nakasongola",
"UG_74","Sembabule",
"UG_77","Arua",
"UG_78","Iganga",
"UG_79","Kabarole",
"UG_80","Kaberamaido",
"UG_81","Kamwenge",
"UG_82","Kanungu",
"UG_83","Kayunga",
"UG_84","Kitgum",
"UG_85","Kyenjojo",
"UG_86","Mayuge",
"UG_87","Mbale",
"UG_88","Moroto",
"UG_89","Mpigi",
"UG_90","Mukono",
"UG_91","Nakapiripirit",
"UG_92","Pader",
"UG_93","Rukungiri",
"UG_94","Sironko",
"UG_95","Soroti",
"UG_96","Wakiso",
"UG_97","Yumbe",
"US_01","Alabama",
"US_02","Alaska",
"US_04","Arizona",
"US_05","Arkansas",
"US_06","California",
"US_08","Colorado",
"US_09","Connecticut",
"US_10","Delaware",
"US_11","District of Columbia",
"US_12","Florida",
"US_13","Georgia",
"US_15","Hawaii",
"US_16","Idaho",
"US_17","Illinois",
"US_18","Indiana",
"US_19","Iowa",
"US_20","Kansas",
"US_21","Kentucky",
"US_22","Louisiana",
"US_23","Maine",
"US_24","Maryland",
"US_25","Massachusetts",
"US_26","Michigan",
"US_27","Minnesota",
"US_28","Mississippi",
"US_29","Missouri",
"US_30","Montana",
"US_31","Nebraska",
"US_32","Nevada",
"US_33","New Hampshire",
"US_34","New Jersey",
"US_35","New Mexico",
"US_36","New York",
"US_37","North Carolina",
"US_38","North Dakota",
"US_39","Ohio",
"US_40","Oklahoma",
"US_41","Oregon",
"US_42","Pennyslvania",
"US_44","Rhode Island",
"US_45","South Carolina",
"US_46","South Dakota",
"US_47","Tennessee",
"US_48","Texas",
"US_49","Utah",
"US_50","Vermont",
"US_51","Virginia",
"US_53","Washington",
"US_54","West Virginia",
"US_55","Wisconsin",
"US_56","Wyoming",
"UY_01","Artigas",
"UY_02","Canelones",
"UY_03","Cerro Largo",
"UY_04","Colonia",
"UY_05","Durazno",
"UY_06","Flores",
"UY_07","Florida",
"UY_08","Lavalleja",
"UY_09","Maldonado",
"UY_10","Montevideo",
"UY_11","Paysandu",
"UY_12","Rio Negro",
"UY_13","Rivera",
"UY_14","Rocha",
"UY_15","Salto",
"UY_16","San Jose",
"UY_17","Soriano",
"UY_18","Tacuarembo",
"UY_19","Treinta y Tres",
"UZ_01","Andijon",
"UZ_02","Bukhoro",
"UZ_03","Farghona",
"UZ_04","Jizzakh",
"UZ_05","Khorazm",
"UZ_06","Namangan",
"UZ_07","Nawoiy",
"UZ_08","Qashqadaryo",
"UZ_09","Qoraqalpoghiston",
"UZ_10","Samarqand",
"UZ_11","Sirdaryo",
"UZ_12","Surkhondaryo",
"UZ_13","Toshkent",
"UZ_14","Toshkent",
"VC_01","Charlotte",
"VC_02","Saint Andrew",
"VC_03","Saint David",
"VC_04","Saint George",
"VC_05","Saint Patrick",
"VC_06","Grenadines",
"VE_01","Amazonas",
"VE_02","Anzoategui",
"VE_03","Apure",
"VE_04","Aragua",
"VE_05","Barinas",
"VE_06","Bolivar",
"VE_07","Carabobo",
"VE_08","Cojedes",
"VE_09","Delta Amacuro",
"VE_11","Falcon",
"VE_12","Guarico",
"VE_13","Lara",
"VE_14","Merida",
"VE_15","Miranda",
"VE_16","Monagas",
"VE_17","Nueva Esparta",
"VE_18","Portuguesa",
"VE_19","Sucre",
"VE_20","Tachira",
"VE_21","Trujillo",
"VE_22","Yaracuy",
"VE_23","Zulia",
"VE_24","Dependencias Federales",
"VE_25","Distrito Federal",
"VE_26","Vargas",
"VN_02","Bac Thai",
"VN_03","Ben Tre",
"VN_05","Cao Bang",
"VN_11","Ha Bac",
"VN_12","Hai Hung",
"VN_13","Hai Phong",
"VN_22","Lai Chau",
"VN_23","Lam Dong",
"VN_24","Long An",
"VN_29","Quang Nam-Da Nang",
"VN_30","Quang Ninh",
"VN_32","Son La",
"VN_33","Tay Ninh",
"VN_34","Thanh Hoa",
"VN_35","Thai Binh",
"VN_37","Tien Giang",
"VN_39","Lang Son",
"VN_43","An Giang",
"VN_44","Dac Lac",
"VN_45","Dong Nai",
"VN_46","Dong Thap",
"VN_47","Kien Giang",
"VN_48","Minh Hai",
"VN_49","Song Be",
"VN_50","Vinh Phu",
"VN_51","Ha Noi",
"VN_52","Ho Chi Minh",
"VN_53","Ba Ria-Vung Tau",
"VN_54","Binh Dinh",
"VN_55","Binh Thuan",
"VN_56","Can Tho",
"VN_57","Gia Lai",
"VN_58","Ha Giang",
"VN_59","Ha Tay",
"VN_60","Ha Tinh",
"VN_61","Hoa Binh",
"VN_62","Khanh Hoa",
"VN_63","Kon Tum",
"VN_64","Lao Cai",
"VN_65","Nam Ha",
"VN_66","Nghe An",
"VN_67","Ninh Binh",
"VN_68","Ninh Thuan",
"VN_69","Phu Yen",
"VN_70","Quang Binh",
"VN_71","Quang Ngai",
"VN_72","Quang Tri",
"VN_73","Soc Trang",
"VN_74","Thua Thien",
"VN_75","Tra Vinh",
"VN_76","Tuyen Quang",
"VN_77","Vinh Long",
"VN_78","Yen Bai",
"VU_05","Ambrym",
"VU_06","Aoba",
"VU_07","Torba",
"VU_08","Efate",
"VU_09","Epi",
"VU_10","Malakula",
"VU_11","Paama",
"VU_12","Pentecote",
"VU_13","Sanma",
"VU_14","Shepherd",
"VU_15","Tafea",
"VU_16","Malampa",
"VU_17","Penama",
"VU_18","Shefa",
"WS_02","Aiga-i-le-Tai",
"WS_03","Atua",
"WS_04","Fa",
"WS_05","Gaga",
"WS_06","Va",
"WS_07","Gagaifomauga",
"WS_08","Palauli",
"WS_09","Satupa",
"WS_10","Tuamasaga",
"WS_11","Vaisigano",
"YE_01","Abyan",
"YE_03","Al Mahrah",
"YE_04","Hadramawt",
"YE_05","Shabwah",
"YE_08","Al Hudaydah",
"YE_10","Al Mahwit",
"YE_11","Dhamar",
"YE_14","Ma'rib",
"YE_15","Sa",
"YE_16","San",
"YE_20","Al Bayda'",
"YE_21","Al Jawf",
"YE_22","Hajjah",
"YE_23","Ibb",
"YE_24","Lahij",
"YE_25","Ta",
"ZA_02","KwaZulu-Natal",
"ZA_03","Free State",
"ZA_05","Eastern Cape",
"ZA_06","Gauteng",
"ZA_07","Mpumalanga",
"ZA_08","Northern Cape",
"ZA_09","Limpopo",
"ZA_10","North-West",
"ZA_11","Western Cape",
"ZM_01","Western",
"ZM_02","Central",
"ZM_03","Eastern",
"ZM_04","Luapula",
"ZM_05","Northern",
"ZM_06","North-Western",
"ZM_07","Southern",
"ZM_08","Copperbelt",
"ZM_09","Lusaka",
"ZR_01","Bandundu",
"ZR_02","Equateur",
"ZR_03","Kasai-Occidental",
"ZR_04","Kasai-Oriental",
"ZR_05","Katanga",
"ZR_06","Kinshasa",
"ZR_07","Kivu",
"ZR_08","Bas-Congo",
"ZR_09","Orientale",
"ZR_10","Maniema",
"ZR_11","Nord-Kivu",
"ZR_12","Sud-Kivu",
"ZW_01","Manicaland",
"ZW_02","Midlands",
"ZW_03","Mashonaland Central",
"ZW_04","Mashonaland East",
"ZW_05","Mashonaland West",
"ZW_06","Matabeleland North",
"ZW_07","Matabeleland South",
"ZW_08","Masvingo",
"ZW_09","Bulawayo",
"ZW_10","Harare"
);
# ----->
sub RegionName($$)
{
my $countrycode = shift || "";
my $regioncode = shift || "";
if ($countrycode eq "us") { return $regus{uc $regioncode} || ""; }
if ($countrycode eq "ca") { return $regca{uc $regioncode} || ""; }
return $regall{uc($countrycode."_".$regioncode)} || "";
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_geoip_city_maxmind {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
$MAXNBOFSECTIONGIR=10;
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin $PluginName: InitParams=$InitParams",1);
my ($mode,$tmpdatafile)=split(/\s+/,$InitParams,2);
my ($datafile,$override)=split(/\+/,$tmpdatafile,2);
if (! $datafile) { $datafile="GeoIPCity.dat"; }
else { $datafile =~ s/%20/ /g; }
if ($type eq 'geoippureperl') {
# With pureperl with always use GEOIP_STANDARD.
# GEOIP_MEMORY_CACHE seems to fail with ActiveState
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
else { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
} else {
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::GEOIP_MEMORY_CACHE(); }
else { $mode=Geo::IP::GEOIP_STANDARD(); }
}
if ($override){ $override =~ s/%20/ /g; $OverrideFile=$override; }
%TmpDomainLookup=();
debug(" Plugin $PluginName: GeoIP initialized type=$type mode=$mode override=$override",1);
if ($type eq 'geoippureperl') {
$geoip_city_maxmind = Geo::IP::PurePerl->open($datafile, $mode);
} else {
$geoip_city_maxmind = Geo::IP->open($datafile, $mode);
}
$LoadedOverride=0;
# Fails on some GeoIP version
# debug(" Plugin geoip_city_maxmind: GeoIP initialized database_info=".$geoip_city_maxmind->database_info());
if ($geoip_city_maxmind) { debug(" Plugin $PluginName: GeoIP plugin and gi object initialized",1); }
else { return "Error: Failed to create gi object for datafile=".$datafile; }
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLMenuLink_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLMenuLink_geoip_city_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
if ($Debug) { debug(" Plugin $PluginName: AddHTMLMenuLink"); }
if ($categ eq 'who') {
$menu->{"plugin_$PluginName"}=2.2; # Pos
$menulink->{"plugin_$PluginName"}=2; # Type of link
$menutext->{"plugin_$PluginName"}=$Message[172]; # Text
}
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLGraph_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLGraph_geoip_city_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
my $ShowCities='H';
$MinHit{'Cities'}=1;
my $total_p; my $total_h; my $total_k;
my $rest_p; my $rest_h; my $rest_k;
if ($Debug) { debug(" Plugin $PluginName: AddHTMLGraph $categ $menu $menulink $menutext"); }
my $title="GeoIP Cities";
&tab_head($title,19,0,'cities');
print "";
print "".$Message[148]." | ";
print "".$Message[171]." | ";
print "".$Message[172].": ".((scalar keys %_city_h)-($_city_h{'unknown'}?1:0))." | ";
if ($ShowCities =~ /P/i) { print "$Message[56] | "; }
if ($ShowCities =~ /P/i) { print "$Message[15] | "; }
if ($ShowCities =~ /H/i) { print "$Message[57] | "; }
if ($ShowCities =~ /H/i) { print "$Message[15] | "; }
if ($ShowCities =~ /B/i) { print "$Message[75] | "; }
if ($ShowCities =~ /L/i) { print "$Message[9] | "; }
print "
\n";
$total_p=$total_h=$total_k=0;
my $count=0;
&BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Cities'},\%_city_h,\%_city_h);
# Group by country
# my @countrylist=('ca','us');
# foreach my $country (@countrylist) {
# print "";
# print "".$countrylib{$country}." | ";
# if ($ShowCities =~ /P/i) { print " | "; }
# if ($ShowCities =~ /P/i) { print " | "; }
# if ($ShowCities =~ /H/i) { print " | "; }
# if ($ShowCities =~ /H/i) { print " | "; }
# if ($ShowCities =~ /B/i) { print " | "; }
# if ($ShowCities =~ /L/i) { print " | "; }
# print "
\n";
foreach my $key (@keylist) {
if ($key eq 'unknown') { next; }
my ($countrycode,$city,$regioncode)=split('_',$key,3);
$city=~s/%20/ /g;
# if ($countrycode ne $country) { next; }
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int(($_city_p{$key}||0)/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($_city_h{$key}/$TotalHits*1000)/10; }
print "";
print "".$DomainsHashIDLib{$countrycode}." | ";
my $regionlib=RegionName($countrycode, $regioncode);
print "".($regionlib?$regionlib:' ')." | ";
print "".ucfirst(EncodeToPageCode($city))." | ";
if ($ShowCities =~ /P/i) { print "".($_city_p{$key}?Format_Number($_city_p{$key}):" ")." | "; }
if ($ShowCities =~ /P/i) { print "".($_city_p{$key}?"$p_p %":' ')." | "; }
if ($ShowCities =~ /H/i) { print "".($_city_h{$key}?Format_Number($_city_h{$key}):" ")." | "; }
if ($ShowCities =~ /H/i) { print "".($_city_h{$key}?"$p_h %":' ')." | "; }
if ($ShowCities =~ /B/i) { print "".Format_Bytes($_city_k{$key})." | "; }
if ($ShowCities =~ /L/i) { print "".($_city_p{$key}?Format_Date($_city_l{$key},1):'-')." | "; }
print "
\n";
$total_p += $_city_p{$key}||0;
$total_h += $_city_h{$key};
$total_k += $_city_k{$key}||0;
$count++;
}
# }
if ($Debug) { debug("Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h",2); }
$rest_p=0;
$rest_h=$TotalHits-$total_h;
$rest_k=0;
if ($rest_p > 0 || $rest_h > 0 || $rest_k > 0) { # All other cities
# print "";
# print " | ";
# if ($ShowCities =~ /P/i) { print " | "; }
# if ($ShowCities =~ /P/i) { print " | "; }
# if ($ShowCities =~ /H/i) { print " | "; }
# if ($ShowCities =~ /H/i) { print " | "; }
# if ($ShowCities =~ /B/i) { print " | "; }
# if ($ShowCities =~ /L/i) { print " | "; }
# print "
\n";
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int($rest_p/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($rest_h/$TotalHits*1000)/10; }
print "";
print "$Message[2]/$Message[0] | ";
if ($ShowCities =~ /P/i) { print "".($rest_p?$rest_p:" ")." | "; }
if ($ShowCities =~ /P/i) { print "".($rest_p?"$p_p %":' ')." | "; }
if ($ShowCities =~ /H/i) { print "".($rest_h?$rest_h:" ")." | "; }
if ($ShowCities =~ /H/i) { print "".($rest_h?"$p_h %":' ')." | "; }
if ($ShowCities =~ /B/i) { print "".Format_Bytes($rest_k)." | "; }
if ($ShowCities =~ /L/i) { print " | "; }
print "
\n";
}
&tab_end();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetCountryCodeByAddr_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# GetCountryCodeByAddr is called to translate an ip into a country code in lower case.
#-----------------------------------------------------------------------------
# Rem: not used
sub GetCountryCodeByAddr_geoip_city_maxmind {
my $param="$_[0]";
# <-----
my $res = TmpLookup_geoip_city_maxmind($param);
if ($type eq 'geoippureperl') {
if (! $res) {
my @record = ();
@record=$geoip_city_maxmind->get_city_record($param) if $geoip_city_maxmind;
my $country;
$country=$record[0] if @record;
$res=lc($country) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: Already resolved to [$res]",5); }
}
else
{
if (! $res) {
my $record=();
$record=$geoip_city_maxmind->record_by_addr($param) if $geoip_city_maxmind;
my $country;
$country=$record->country if $record;
$res=lc($country) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: Already resolved to [$res]",5); }
}
# ----->
return $res;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetCountryCodeByName_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# GetCountryCodeByName is called to translate a host name into a country code in lower case.
#-----------------------------------------------------------------------------
# Rem: not used
sub GetCountryCodeByName_geoip_city_maxmind {
my $param="$_[0]";
# <-----
my $res = TmpLookup_geoip_city_maxmind($param);
if ($type eq 'geoippureperl') {
if (! $res) {
my @record = ();
@record=$geoip_city_maxmind->get_city_record($param) if $geoip_city_maxmind;
my $country;
$country=$record[0] if @record;
$res=lc($country) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: Already resolved to [$res]",5); }
}
else
{
if (! $res) {
my $record=();
$record=$geoip_city_maxmind->record_by_name($param) if $geoip_city_maxmind;
my $country;
$country=$record->country if $record;
$res=lc($country) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: Already resolved to [$res]",5); }
}
# ----->
return $res;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: ShowInfoHost_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to add additionnal columns to the Hosts report.
# This function is called when building rows of the report (One call for each
# row). So it allows you to add a column in report, for example with code :
# print "This is a new cell for $param | ";
# Parameters: Host name or ip
#-----------------------------------------------------------------------------
sub ShowInfoHost_geoip_city_maxmind {
my $param="$_[0]";
# <-----
if ($param eq '__title__')
{
my $NewLinkParams=${QueryString};
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)output(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
my $NewLinkTarget='';
if ($DetailedReportsOnNewWindows) { $NewLinkTarget=" target=\"awstatsbis\""; }
if (($FrameName eq 'mainleft' || $FrameName eq 'mainright') && $DetailedReportsOnNewWindows < 2) {
$NewLinkParams.="&framename=mainright";
$NewLinkTarget=" target=\"mainright\"";
}
$NewLinkParams =~ s/(&|&)+/&/i;
$NewLinkParams =~ s/^&//; $NewLinkParams =~ s/&$//;
if ($NewLinkParams) { $NewLinkParams="${NewLinkParams}&"; }
# print "";
# print "GeoIP Country";
# print " | ";
print "";
print "GeoIP City";
print " | ";
}
elsif ($param)
{
# try loading our override file if we haven't yet
my $ip=0;
my $key;
if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
$ip=4;
$key=$param;
}
elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address
$ip=6;
$key=$param;
}
if ($key && $ip==4) {
my $country;
my $city;
my @res = TmpLookup_geoip_city_maxmind($param);
if (@res){
$country = $res[0];
$city = $res[4];
}
elsif ($type eq 'geoippureperl')
{
my @record = ();
@record=$geoip_city_maxmind->get_city_record($param) if $geoip_city_maxmind;
if ($Debug) { debug(" Plugin $PluginName: GetCityByIp for $param: [@record]",5); }
$country=$record[0] if @record;
$city=$record[4] if @record;
}
else
{
my $record=();
$record=$geoip_city_maxmind->record_by_addr($param) if $geoip_city_maxmind;
if ($Debug) { debug(" Plugin $PluginName: GetCityByIp for $param: [$record]",5); }
$country=$record->country_code if $record;
$city=$record->city if $record;
}
# print "";
# if ($country) { print $DomainsHashIDLib{$country}?$DomainsHashIDLib{$country}:"$Message[0]"; }
# else { print "$Message[0]"; }
# print " | ";
print "";
if ($city) { print EncodeToPageCode($city); }
else { print "$Message[0]"; }
print " | ";
}
if ($key && $ip==6) {
debug (" Plugin $PluginName: IPv6 not supported by GeoIP: $key");
print "";
print "$Message[0]";
print " | ";
}
if (! $key) {
my $country;
my $city;
my @res = TmpLookup_geoip_city_maxmind($param);
if (@res){
$country = $res[0];
$city = $res[4];
}
elsif ($type eq 'geoippureperl')
{
my @record = ();
@record=$geoip_city_maxmind->get_city_record($param) if $geoip_city_maxmind;
if ($Debug) { debug(" Plugin $PluginName: GetCityByHostname for $param: [@record]",5); }
$country=$record[0] if @record;
$city=$record[4] if @record;
}
else
{
my $record=();
$record=$geoip_city_maxmind->record_by_name($param) if $geoip_city_maxmind;
if ($Debug) { debug(" Plugin $PluginName: GetCityByHostname for $param: [$record]",5); }
$country=$record->country_code if $record;
$city=$record->city if $record;
}
# print "";
# if ($country) { print $DomainsHashIDLib{$country}?$DomainsHashIDLib{$country}:"$Message[0]"; }
# else { print "$Message[0]"; }
# print " | ";
print "";
if ($city) { print EncodeToPageCode($city); }
else { print "$Message[0]"; }
print " | ";
}
}
else
{ print " | "; }
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionInitHashArray_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionInitHashArray_geoip_city_maxmind {
# my $param="$_[0]";
# <-----
if ($Debug) { debug(" Plugin $PluginName: Init_HashArray"); }
%_city_p = %_city_h = %_city_k = %_city_l =();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessIP_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessIp_geoip_city_maxmind {
my $param="$_[0]"; # Param must be an IP
# <-----
if ($type eq 'geoippureperl') {
my @record = TmpLookup_geoip_city_maxmind($param);
if (!@record){
@record=$geoip_city_maxmind->get_city_record($param) if $geoip_city_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetCityByName for $param: [@record]",5); }
if (@record) {
my $city=$record[4];
if ($city) {
my $countrycity=$record[0].'_'.$city;
$countrycity=~s/ /%20/g;
if ($record[3]) { $countrycity.='_'.$record[3]; }
$_city_h{lc($countrycity)}++;
} else {
$_city_h{'unknown'}++;
}
} else {
$_city_h{'unknown'}++;
}
}
else
{
my $record=();
my @rec = TmpLookup_geoip_city_maxmind($param);
if (@rec){
$record->city = $rec[4];
$record->region = $rec[0];
$record->country_code = $rec[3];
}else{
$record=$geoip_city_maxmind->record_by_addr($param) if $geoip_city_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetCityByIp for $param: [$record]",5); }
if ($record) {
my $city=$record->city;
# if ($PageBool) { $_city_p{$city}++; }
if ($city) {
my $countrycity=$record->country_code.'_'.$record->city;
$countrycity=~s/ /%20/g;
if ($record->region) { $countrycity.='_'.$record->region; }
$_city_h{lc($countrycity)}++;
} else {
$_city_h{'unknown'}++;
}
# if ($timerecord > $_city_l{$city}) { $_city_l{$city}=$timerecord; }
} else {
$_city_h{'unknown'}++;
}
}
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessHostname_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessHostname_geoip_city_maxmind {
my $param="$_[0]"; # Param must be an IP
if ($type eq 'geoippureperl') {
my @record = TmpLookup_geoip_city_maxmind($param);
if (!@record){
@record=$geoip_city_maxmind->get_city_record($param) if $geoip_city_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetCityByName for $param: [@record]",5); }
if (@record) {
my $city=$record[4];
if ($city) {
my $countrycity=$record[0].'_'.$city;
$countrycity=~s/ /%20/g;
if ($record[3]) { $countrycity.='_'.$record[3]; }
$_city_h{lc($countrycity)}++;
} else {
$_city_h{'unknown'}++;
}
} else {
$_city_h{'unknown'}++;
}
}
else
{
my $record=();
my @rec = TmpLookup_geoip_city_maxmind($param);
if (@rec){
$record->city = $rec[4];
$record->region = $rec[3];
$record->country_code = $rec[0];
}else{
$record=$geoip_city_maxmind->record_by_name($param) if $geoip_city_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetCityByName for $param: [$record]",5); }
if ($record) {
my $city=$record->city;
# if ($PageBool) { $_city_p{$city}++; }
if ($city) {
my $countrycity=($record->country_code).'_'.$city;
$countrycity=~s/ /%20/g;
if ($record->region) { $countrycity.='_'.$record->region; }
$_city_h{lc($countrycity)}++;
} else {
$_city_h{'unknown'}++;
}
# if ($timerecord > $_city_l{$city}) { $_city_l{$city}=$timerecord; }
} else {
$_city_h{'unknown'}++;
}
}
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionReadHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionReadHistory_geoip_city_maxmind {
my $issectiontoload=shift;
my $xmlold=shift;
my $xmleb=shift;
my $countlines=shift;
# <-----
if ($Debug) { debug(" Plugin $PluginName: Begin of PLUGIN_geoip_city_maxmind section"); }
my @field=();
my $count=0;my $countloaded=0;
do {
if ($field[0]) {
$count++;
if ($issectiontoload) {
$countloaded++;
if ($field[2]) { $_city_h{$field[0]}+=$field[2]; }
}
}
$_=;
chomp $_; s/\r//;
@field=split(/\s+/,($xmlold?XMLDecodeFromHisto($_):$_));
$countlines++;
}
until ($field[0] eq "END_PLUGIN_$PluginName" || $field[0] eq "${xmleb}END_PLUGIN_$PluginName" || ! $_);
if ($field[0] ne "END_PLUGIN_$PluginName" && $field[0] ne "${xmleb}END_PLUGIN_$PluginName") { error("History file is corrupted (End of section PLUGIN not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).","","",1); }
if ($Debug) { debug(" Plugin $PluginName: End of PLUGIN_$PluginName section ($count entries, $countloaded loaded)"); }
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionWriteHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionWriteHistory_geoip_city_maxmind {
my ($xml,$xmlbb,$xmlbs,$xmlbe,$xmlrb,$xmlrs,$xmlre,$xmleb,$xmlee)=(shift,shift,shift,shift,shift,shift,shift,shift,shift);
if ($Debug) { debug(" Plugin $PluginName: SectionWriteHistory_$PluginName start - ".(scalar keys %_city_h)); }
# <-----
print HISTORYTMP "\n";
if ($xml) { print HISTORYTMP "$MAXNBOFSECTIONGIR\n"; }
print HISTORYTMP "# Plugin key - Pages - Hits - Bandwidth - Last access\n";
#print HISTORYTMP "# The $MaxNbOfExtra[$extranum] first number of hits are first\n";
$ValueInFile{"plugin_$PluginName"}=tell HISTORYTMP;
print HISTORYTMP "${xmlbb}BEGIN_PLUGIN_$PluginName${xmlbs}".(scalar keys %_city_h)."${xmlbe}\n";
&BuildKeyList($MAXNBOFSECTIONGIR,1,\%_city_h,\%_city_h);
my %keysinkeylist=();
foreach (@keylist) {
$keysinkeylist{$_}=1;
#my $page=$_city_p{$_}||0;
#my $bytes=$_city_k{$_}||0;
#my $lastaccess=$_city_l{$_}||'';
print HISTORYTMP "${xmlrb}".XMLEncodeForHisto($_)."${xmlrs}0${xmlrs}", $_city_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
foreach (keys %_city_h) {
if ($keysinkeylist{$_}) { next; }
#my $page=$_city_p{$_}||0;
#my $bytes=$_city_k{$_}||0;
#my $lastaccess=$_city_l{$_}||'';
print HISTORYTMP "${xmlrb}".XMLEncodeForHisto($_)."${xmlrs}0${xmlrs}", $_city_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
print HISTORYTMP "${xmleb}END_PLUGIN_$PluginName${xmlee}\n";
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: LoadOverrideFile
# Attempts to load a comma delimited file that will override the GeoIP database
# Useful for Intranet records
# CSV format: IP,2-char Country code, region, city, postal code, latitude,
# longitude, US metro code, US area code
#-----------------------------------------------------------------------------
sub LoadOverrideFile_geoip_city_maxmind{
my $filetoload="";
if ($OverrideFile){
if (!open(GEOIPFILE, $OverrideFile)){
debug("Plugin $PluginName: Unable to open override file: $OverrideFile");
$LoadedOverride = 1;
return;
}
}else{
my $conf = (exists(&Get_Config_Name) ? Get_Config_Name() : $SiteConfig);
if ($conf && open(GEOIPFILE,"$DirData/$PluginName.$conf.txt")) { $filetoload="$DirData/$PluginName.$conf.txt"; }
elsif (open(GEOIPFILE,"$DirData/$PluginName.txt")) { $filetoload="$DirData/$PluginName.txt"; }
else { debug("No override file \"$DirData/$PluginName.txt\": $!"); }
}
if ($filetoload)
{
# This is the fastest way to load with regexp that I know
while (){
chomp $_;
s/\r//;
my @record = split(",", $_);
# replace quotes if they were used in the file
foreach (@record){ $_ =~ s/"//g; }
# now we need to copy our file values in the order to mimic the lookup values
my @res = ();
$res[0] = $record[1];
$res[3] = $record[2];
$res[4] = $record[3];
$res[5] = $record[4];
$res[6] = $record[5];
$res[7] = $record[6];
$res[8] = $record[7];
$res[9] = $record[8];
# store in hash
$TmpDomainLookup{$record[0]} = [@res];
}
close GEOIPFILE;
debug(" Plugin $PluginName: Overload file loaded: ".(scalar keys %TmpDomainLookup)." entries found.");
}
$LoadedOverride = 1;
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: TmpLookup
# Searches the temporary hash for the parameter value and returns the corresponding
# GEOIP entry
#-----------------------------------------------------------------------------
sub TmpLookup_geoip_city_maxmind(){
$param = shift;
if (!$LoadedOverride){&LoadOverrideFile_geoip_city_maxmind();}
# my @val = ();
# if ($geoip_city_maxmind &&
# (($type eq 'geoip' && $geoip_city_maxmind->VERSION >= 1.30) ||
# $type eq 'geoippureperl' && $geoip_city_maxmind->VERSION >= 1.17)){
# @val = @{$TmpDomainLookup{$geoip_city_maxmind->get_ip_address($param)}};
# }
# else {@val = @{$TmpDomainLookup{$param};}}
# return @val;
if ($TmpDomainLookup{$param}) { return @{$TmpDomainLookup{$param};} }
else { return; }
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/hostinfo.pm 0000640 0001750 0001750 00000015650 12410217071 017574 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# HostInfo AWStats plugin
# This plugin allow you to add information on hosts, like whois fields.
#-----------------------------------------------------------------------------
# Perl Required Modules: XWhois
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
push @INC, "${DIR}/plugins";
if (!eval ('require "Net/XWhois.pm";')) { return $@?"Error: $@":"Error: Need Perl module Net::XWhois"; }
if (!eval ('require "Digest/MD5.pm";')) { return $@?"Error: $@":"Error: Need Perl module Digest::MD5"; }
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="6.0";
my $PluginHooksFunctions="ShowInfoHost AddHTMLBodyHeader BuildFullHTMLOutput";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_hostinfo {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin hostinfo: InitParams=$InitParams",1);
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLBodyHeader_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to Add HTML code at beginning of BODY section.
# Parameters: None
#-----------------------------------------------------------------------------
sub AddHTMLBodyHeader_hostinfo {
# <-----
my $WIDTHINFO=640;
my $HEIGHTINFO=480;
my $urlparam="pluginmode=hostinfo&config=$SiteConfig";
$urlparam.=($DirConfig?"&configdir=$DirConfig":"");
print <
function neww(a,b) {
var wfeatures="directories=0,menubar=1,status=0,resizable=1,scrollbars=1,toolbar=0,width=$WIDTHINFO,height=$HEIGHTINFO,left=" + eval("(screen.width - $WIDTHINFO)/2") + ",top=" + eval("(screen.height - $HEIGHTINFO)/2");
EOF
print "fen=window.open('".XMLEncode("$AWScript?$urlparam&host")."='+a+'".XMLEncode("&key")."='+b,'whois',wfeatures);\n";
print <
EOF
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: ShowInfoHost_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to add additionnal columns to the Hosts report.
# This function is called when building rows of the report (One call for each
# row). So it allows you to add a column in report, for example with code :
# print "This is a new cell for $param | ";
# Parameters: Host name or ip
#-----------------------------------------------------------------------------
sub ShowInfoHost_hostinfo {
my $param="$_[0]";
# <-----
if ($param eq '__title__') {
print "$Message[114] | ";
}
elsif ($param) {
my $keyforwhois;
if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
$keyforwhois=$param;
}
elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address
$keyforwhois=$param;
}
else { # Hostname
$param =~ /([-\w]+\.[-\w]+\.(?:au|uk|jp|nz))$/ or $param =~ /([-\w]+\.[-\w]+)$/;
$keyforwhois=$1;
}
print "";
# if ($keyforwhois) { print "?"; }
if ($keyforwhois) { print "?"; }
else { print " " }
print " | ";
}
else {
print " | ";
}
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNTION: BuildFullHTMLOutput_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to output an HTML page completely built by plugin instead
# of AWStats output
#-----------------------------------------------------------------------------
sub BuildFullHTMLOutput_hostinfo {
# <-----
my $Host='';
if ($QueryString =~ /host=([^&]+)/i) {
$Host=lc(&DecodeEncodedString("$1"));
}
my $ip='';
my $HostResolved='';
# my $regipv4=qr/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
# my $regipv6=qr/^[0-9A-F]*:/i;
# if ($Host =~ /$regipv4/o) { $ip=4; }
# elsif ($Host =~ /$regipv6/o) { $ip=6; }
# if ($ip == 4) {
# my $lookupresult=lc(gethostbyaddr(pack("C4",split(/\./,$Host)),AF_INET)); # This is very slow, may spend 20 seconds
# if (! $lookupresult || $lookupresult =~ /$regipv4/o || ! IsAscii($lookupresult)) {
# $HostResolved='*';
# }
# else {
# $HostResolved=$lookupresult;
# }
# if ($Debug) { debug(" Reverse DNS lookup for $Host done: $HostResolved",4); }
# }
if (! $ip) { $HostResolved=$Host; }
if ($Debug) { debug(" Plugin hostinfo: DirData=$DirData Host=$Host HostResolved=$HostResolved ",4); }
my $w = new Net::XWhois Verbose=>$Debug, Cache=>$DirData, NoCache=>0, Timeout=>10, Domain=>$HostResolved;
print "
\n";
if ($w && $w->response()) {
&tab_head("Common Whois Fields",0,0,'whois');
print "Common field info | Value |
\n";
print "Name | ".($w->name())." |
";
print "Status | ".($w->status())." |
";
print "NameServers | ".($w->nameservers())." |
";
print "Registrant | ".($w->registrant())." |
";
print "Contact Admin | ".($w->contact_admin())." |
";
print "Contact Tech | ".($w->contact_tech())." |
";
print "Contact Billing | ".($w->contact_billing())." |
";
print "Contact Zone | ".($w->contact_zone())." |
";
print "Contact Emails | ".($w->contact_emails())." |
";
print "Contact Handles | ".($w->contact_handles())." |
";
print "Domain Handles | ".($w->domain_handles())." |
";
&tab_end;
}
&tab_head("Full Whois Field",0,0,'whois');
if ($w && $w->response()) {
print "".($w->response())." |
\n";
}
else {
print " The Whois command failed. Did the server running AWStats is allowed to send WhoIs queries (If a firewall is running, port 43 should be opened from inside to outside) ?
|
\n";
}
&tab_end;
return 1;
# ----->
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/geoip6.pm 0000640 0001750 0001750 00000024056 12410217071 017134 0 ustar sk sk #!/usr/bin/perl
# extended geoip.pm by Sven Strickroth
#-----------------------------------------------------------------------------
# GeoIP Maxmind AWStats plugin with IPv6 support
# This plugin allow you to get country report with countries detected
# from a Geographical database (GeoIP internal database) instead of domain
# hostname suffix.
# This works with IPv4 and also IPv6
# Needs the IPv6 country database from Maxmind (free).
#-----------------------------------------------------------------------------
# Perl Required Modules: Geo::IP (Geo::IP::PurePerl does not support IPv6 yet)
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
use vars qw/ $type /;
$type='geoip';
if (!eval ('require "Geo/IP.pm";')) {
$error1=$@;
# $type='geoippureperl';
# if (!eval ('require "Geo/IP/PurePerl.pm";')) {
# $error2=$@;
# $ret=($error1||$error2)?"Error:\n$error1$error2":"";
$ret.="Error: Need Perl module Geo::IP";
return $ret;
# }
} else {
Geo::IP->VERSION >= 1.40 || die("Requires Geo/IP.pm >= 1.40");
}
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="5.4";
my $PluginHooksFunctions="GetCountryCodeByAddr GetCountryCodeByName ShowInfoHost";
my $PluginName = "geoip6";
my $LoadedOverride=0;
my $OverrideFile="";
my %TmpDomainLookup;
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$gi
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_geoip6 {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin $PluginName: InitParams=$InitParams",1);
my ($mode,$tmpdatafile)=split(/\s+/,$InitParams,2);
my ($datafile,$override)=split(/\+/,$tmpdatafile,2);
if (! $datafile) { $datafile="$PluginName.dat"; }
else { $datafile =~ s/%20/ /g; }
if ($type eq 'geoippureperl') {
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::PurePerl::GEOIP_MEMORY_CACHE(); }
else { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
} else {
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::GEOIP_MEMORY_CACHE(); }
else { $mode=Geo::IP::GEOIP_STANDARD(); }
}
if ($override){$OverrideFile=$override;}
%TmpDomainLookup=();
debug(" Plugin $PluginName: GeoIP initialized type=$type mode=$mode override=$override",1);
if ($type eq 'geoippureperl') {
$gi = Geo::IP::PurePerl->open($datafile, $mode);
} else {
$gi = Geo::IP->open($datafile, $mode);
}
# Fails on some GeoIP version
# debug(" Plugin geoip6: GeoIP initialized database_info=".$gi->database_info());
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetCountryCodeByAddr_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# GetCountryCodeByAddr is called to translate an ip into a country code in lower case.
#-----------------------------------------------------------------------------
sub GetCountryCodeByAddr_geoip6 {
my $param="$_[0]";
# <-----
if (! $param) { return ''; }
my $searchkey;
if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
$searchkey = '::'.$param;
} else {
$searchkey = $param;
}
my $res= TmpLookup_geoip6($param);
if (! $res) {
$res=lc($gi->country_code_by_addr_v6($searchkey)) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $searchkey: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: Already resolved to [$res]",5); }
# ----->
return $res;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetCountryCodeByName_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# GetCountryCodeByName is called to translate a host name into a country code in lower case.
#-----------------------------------------------------------------------------
sub GetCountryCodeByName_geoip6 {
my $param="$_[0]";
# <-----
if (! $param) { return ''; }
my $res = TmpLookup_geoip6($param);
if (! $res) {
$res=lc($gi->country_code_by_name_v6($param)) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: Already resolved to [$res]",5); }
# ----->
return $res;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: ShowInfoHost_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to add additionnal columns to the Hosts report.
# This function is called when building rows of the report (One call for each
# row). So it allows you to add a column in report, for example with code :
# print "This is a new cell for $param | ";
# Parameters: Host name or ip
#-----------------------------------------------------------------------------
sub ShowInfoHost_geoip6 {
my $param="$_[0]";
# <-----
if ($param eq '__title__') {
my $NewLinkParams=${QueryString};
$NewLinkParams =~ s/(^|&)update(=\w*|$)//i;
$NewLinkParams =~ s/(^|&)output(=\w*|$)//i;
$NewLinkParams =~ s/(^|&)staticlinks(=\w*|$)//i;
$NewLinkParams =~ s/(^|&)framename=[^&]*//i;
my $NewLinkTarget='';
if ($DetailedReportsOnNewWindows) { $NewLinkTarget=" target=\"awstatsbis\""; }
if (($FrameName eq 'mainleft' || $FrameName eq 'mainright') && $DetailedReportsOnNewWindows < 2) {
$NewLinkParams.="&framename=mainright";
$NewLinkTarget=" target=\"mainright\"";
}
$NewLinkParams =~ tr/&/&/s; $NewLinkParams =~ s/^&//; $NewLinkParams =~ s/&$//;
if ($NewLinkParams) { $NewLinkParams="${NewLinkParams}&"; }
print "";
print "GeoIP Country";
print " | ";
}
elsif ($param) {
my $ip=0;
my $key;
if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
$ip=4;
$key='::'.$param;
}
elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address
$ip=6;
$key=$param;
}
print "";
if ($key) {
my $res = TmpLookup_geoip6($param);
if (!$res && $gi) {
$res=lc($gi->country_code_by_addr_v6($key));
}
if ($Debug) { debug(" Plugin $PluginName: GetCountryByIp for $key: [$res]",5); }
if ($res) { print $DomainsHashIDLib{$res}?$DomainsHashIDLib{$res}:"$Message[0]"; }
else { print "$Message[0]"; }
}
else {
my $res = TmpLookup_geoip6($param);
if (!$res){$res=lc($gi->country_code_by_name_v6($param)) if $gi;}
if ($Debug) { debug(" Plugin $PluginName: GetCountryByHostname for $param: [$res]",5); }
if ($res) { print $DomainsHashIDLib{$res}?$DomainsHashIDLib{$res}:"$Message[0]"; }
else { print "$Message[0]"; }
}
print " | ";
}
else {
print " | ";
}
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: LoadOverrideFile
# Attempts to load a comma delimited file that will override the GeoIP database
# Useful for Intranet records
# CSV format: IP,2-char Country code
#-----------------------------------------------------------------------------
sub LoadOverrideFile_geoip6{
my $filetoload="";
if ($OverrideFile){
if (!open(GEOIPFILE, $OverrideFile)){
debug("Plugin $PluginName: Unable to open override file: $OverrideFile");
$LoadedOverride = 1;
return;
}
}else{
my $conf = (exists(&Get_Config_Name) ? Get_Config_Name() : $SiteConfig);
if ($conf && open(GEOIPFILE,"$DirData/$PluginName.$conf.txt")) { $filetoload="$DirData/$PluginName.$conf.txt"; }
elsif (open(GEOIPFILE,"$DirData/$PluginName.txt")) { $filetoload="$DirData/$PluginName.txt"; }
else { debug("No override file \"$DirData/$PluginName.txt\": $!"); }
}
if ($filetoload)
{
# This is the fastest way to load with regexp that I know
while (){
chomp $_;
s/\r//;
my @record = split(",", $_);
# replace quotes if they were used in the file
foreach (@record){ $_ =~ s/"//g; }
# store in hash
$TmpDomainLookup{$record[0]} = $record[1];
}
close GEOIPFILE;
debug(" Plugin $PluginName: Overload file loaded: ".(scalar keys %TmpDomainLookup)." entries found.");
}
$LoadedOverride = 1;
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: TmpLookup
# Searches the temporary hash for the parameter value and returns the corresponding
# GEOIP entry
#-----------------------------------------------------------------------------
sub TmpLookup_geoip6(){
$param = shift;
if (!$LoadedOverride){&LoadOverrideFile_geoip6();}
#my $val;
#if ($gi &&
#(($type eq 'geoip' && $gi->VERSION >= 1.30) ||
# $type eq 'geoippureperl' && $gi->VERSION >= 1.17)){
# $val = $TmpDomainLookup{$gi->get_ip_address($param)};
#}
#else {$val = $TmpDomainLookup{$param};}
#return $val || '';
return $TmpDomainLookup{$param}||'';
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/hashfiles.pm 0000640 0001750 0001750 00000012021 12410217071 017676 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# HashFiles AWStats plugin
# Allows AWStats to read/save its data file as native hash files.
# This increase read andwrite files operations.
#-----------------------------------------------------------------------------
# Perl Required Modules: Storable
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
if (!eval ('require "Storable.pm";')) { return $@?"Error: $@":"Error: Need Perl module Storable"; }
# ----->
use strict;no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="5.1";
my $PluginHooksFunctions="SearchFile LoadCache SaveHash";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$PluginHashfilesUpToDate
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_hashfiles {
my $InitParams=shift;
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
$PluginHashfilesUpToDate=1;
# ----->
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNTION: SearchFile_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
#-----------------------------------------------------------------------------
sub SearchFile_hashfiles {
my ($searchdir,$dnscachefile,$filesuffix,$dnscacheext,$filetoload)=@_; # Get params sent by ref
if (-f "${searchdir}$dnscachefile$filesuffix.hash") {
my ($tmp1a,$tmp2a,$tmp3a,$tmp4a,$tmp5a,$tmp6a,$tmp7a,$tmp8a,$tmp9a,$datesource,$tmp10a,$tmp11a,$tmp12a) = stat("${searchdir}$dnscachefile$filesuffix$dnscacheext");
my ($tmp1b,$tmp2b,$tmp3b,$tmp4b,$tmp5b,$tmp6b,$tmp7b,$tmp8b,$tmp9b,$datehash,$tmp10b,$tmp11b,$tmp12b) = stat("${searchdir}$dnscachefile$filesuffix.hash");
if ($datesource && $datehash < $datesource) {
$PluginHashfilesUpToDate=0;
debug(" Plugin hashfiles: Hash file not up to date. Will use source file $filetoload instead.");
}
else {
# There is no source file or there is and hash file is up to date. We can just load hash file
$filetoload="${searchdir}$dnscachefile$filesuffix.hash";
}
}
elsif ($filetoload) {
$PluginHashfilesUpToDate=0;
debug(" Plugin hashfiles: Hash file not found. Will use source file $filetoload instead.");
}
# Change calling params
$_[4]=$filetoload;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: LoadCache_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
#-----------------------------------------------------------------------------
sub LoadCache_hashfiles {
my ($filetoload,$hashtoload)=@_;
if ($filetoload =~ /\.hash$/) {
# There is no source file or there is and hash file is up to date. We can just load hash file
eval('%$hashtoload = %{ Storable::retrieve("$filetoload") };') || warning("Warning: Error while retrieving hashfile: $@");
}
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SaveHash_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
#-----------------------------------------------------------------------------
sub SaveHash_hashfiles {
my ($filetosave,$hashtosave,$testifuptodate,$nbmaxofelemtosave,$nbofelemsaved)=@_;
if (! $testifuptodate || ! $PluginHashfilesUpToDate) {
$filetosave =~ s/(\.\w+)$//; $filetosave.=".hash";
debug(" Plugin hashfiles: Save data ".($nbmaxofelemtosave?"($nbmaxofelemtosave records max)":"(all records)")." into hash file $filetosave");
if (! $nbmaxofelemtosave || (scalar keys %$hashtosave <= $nbmaxofelemtosave)) {
# Save all hash array
unless ( eval('Storable::store(\%$hashtosave, "$filetosave");') ) {
$_[4] = 0;
warning("Warning: Error while storing hashfile: $@");
return;
}
$_[4]=scalar keys %$hashtosave;
}
else {
debug(" Plugin hashfiles: We need to resize hash to save from ".(scalar keys %$hashtosave)." to $nbmaxofelemtosave");
# Save part of hash array
my $counter=0;
my %newhashtosave=();
foreach my $key (keys %$hashtosave) {
$newhashtosave{$key}=$hashtosave->{$key};
if (++$counter >= $nbmaxofelemtosave) { last; }
}
unless ( eval('Storable::store(\%newhashtosave, "$filetosave");') ) {
$_[4] = 0;
warning("Warning: Error while storing hashfile: $@");
return;
}
$_[4]=scalar keys %newhashtosave;
}
$_[0]=$filetosave;
}
else {
$_[4]=0;
}
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/rawlog.pm 0000640 0001750 0001750 00000011016 12410217071 017226 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# Rawlog AWStats plugin
# This plugin adds a form in AWStats main page to allow users to see raw
# content of current log files. A filter is also available.
#-----------------------------------------------------------------------------
# Perl Required Modules: None
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES.
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="5.7";
my $PluginHooksFunctions="AddHTMLBodyHeader BuildFullHTMLOutput";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$MAXLINE
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_rawlog {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin rawlog: InitParams=$InitParams",1);
if ($QueryString =~ /rawlog_maxlines=(\d+)/i) { $MAXLINE=&DecodeEncodedString("$1"); }
else { $MAXLINE=5000; }
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNTION: AddHTMLBodyHeader_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to Add HTML code at beginning of BODY section.
#-----------------------------------------------------------------------------
sub AddHTMLBodyHeader_rawlog {
# <-----
# Show form only if option -staticlinks not used
if (! $StaticLinks) { &_ShowForm(''); }
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNTION: BuildFullHTMLOutput_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to output an HTML page completely built by plugin instead
# of AWStats output
#-----------------------------------------------------------------------------
sub BuildFullHTMLOutput_rawlog {
# <-----
my $Filter='';
if ($QueryString =~ /filterrawlog=([^&]+)/i) { $Filter=&DecodeEncodedString("$1"); }
# A security check
if ($QueryString =~ /logfile=/i) {
print "
Option logfile is not allowed while building rawlog output.
";
return 0;
}
# Show form
&_ShowForm($Filter);
# Precompiled regex Filter to speed up scan
if ($Filter) { $Filter=qr/$Filter/i; }
print "
\n";
# Show raws
my $xml=($BuildReportFormat eq 'xhtml');
open(LOG,"$LogFile") || error("Couldn't open server log file \"$LogFile\" : $!");
binmode LOG; # Avoid premature EOF due to log files corrupted with \cZ or bin chars
my $i=0;
print "";
while () {
chomp $_; $_ =~ s/\r//;
if ($Filter && $_ !~ /$Filter/o) { next; }
print ($xml?XMLEncode("$_"):"$_");
print "\n";
if (++$i >= $MAXLINE) { last; }
}
print "
\n$i lines.
";
return 1;
# ----->
}
sub _ShowForm {
my $Filter=shift||'';
print "
\n";
print "\n";
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/geoip_org_maxmind.pm 0000640 0001750 0001750 00000046406 12410217071 021435 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# GeoIp_Org_Maxmind AWStats plugin
# This plugin allow you to add a city report.
# Need the licensed ISP database from Maxmind.
#-----------------------------------------------------------------------------
# Perl Required Modules: Geo::IP or Geo::IP::PurePerl
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
use vars qw/ $type /;
$type='geoip';
if (!eval ('require "Geo/IP.pm";')) {
$error1=$@;
$type='geoippureperl';
if (!eval ('require "Geo/IP/PurePerl.pm";')) {
$error2=$@;
$ret=($error1||$error2)?"Error:\n$error1$error2":"";
$ret.="Error: Need Perl module Geo::IP or Geo::IP::PurePerl";
return $ret;
}
}
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="6.2";
my $PluginHooksFunctions="AddHTMLMenuLink AddHTMLGraph ShowInfoHost SectionInitHashArray SectionProcessIp SectionProcessHostname SectionReadHistory SectionWriteHistory";
my $PluginName="geoip_org_maxmind";
my $LoadedOverride=0;
my $OverrideFile="";
my %TmpDomainLookup;
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$geoip_org_maxmind
%_org_p
%_org_h
%_org_k
%_org_l
$MAXNBOFSECTIONGIR
$MAXLENGTH
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_geoip_org_maxmind {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
$MAXNBOFSECTIONGIR=10;
$MAXLENGTH=50;
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin $PluginName: InitParams=$InitParams",1);
my ($mode,$tmpdatafile)=split(/\s+/,$InitParams,2);
my ($datafile,$override)=split(/\+/,$tmpdatafile,2);
if (! $datafile) { $datafile="GeoIPOrg.dat"; }
else { $datafile =~ s/%20/ /g; }
if ($type eq 'geoippureperl') {
# With pureperl with always use GEOIP_STANDARD.
# GEOIP_MEMORY_CACHE seems to fail with ActiveState
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
else { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
} else {
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::GEOIP_MEMORY_CACHE(); }
else { $mode=Geo::IP::GEOIP_STANDARD(); }
}
if ($override){ $override =~ s/%20/ /g; $OverrideFile=$override; }
%TmpDomainLookup=();
debug(" Plugin $PluginName: GeoIP initialized type=$type mode=$mode",1);
if ($type eq 'geoippureperl') {
$geoip_org_maxmind = Geo::IP::PurePerl->open($datafile, $mode);
} else {
$geoip_org_maxmind = Geo::IP->open($datafile, $mode);
}
$LoadedOverride=0;
# Fails on some GeoIP version
# debug(" Plugin $PluginName: GeoIP initialized database_info=".$geoip_org_maxmind->database_info());
if ($geoip_org_maxmind) { debug(" Plugin $PluginName: GeoIP plugin and gi object initialized",1); }
else { return "Error: Failed to create gi object for datafile=".$datafile; }
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLMenuLink_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLMenuLink_geoip_org_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
if ($Debug) { debug(" Plugin $PluginName: AddHTMLMenuLink"); }
if ($categ eq 'who') {
$menu->{"plugin_$PluginName"}=0.5; # Pos
$menulink->{"plugin_$PluginName"}=2; # Type of link
$menutext->{"plugin_$PluginName"}="Organizations"; # Text
}
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLGraph_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLGraph_geoip_org_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
my $ShowISP='H';
$MinHit{'Org'}=1;
my $total_p; my $total_h; my $total_k;
my $rest_p; my $rest_h; my $rest_k;
if ($Debug) { debug(" Plugin $PluginName: AddHTMLGraph $categ $menu $menulink $menutext"); }
my $title='Organizations';
&tab_head("$title",19,0,'org');
print "Organizations : ".((scalar keys %_org_h)-($_org_h{'unknown'}?1:0))." | ";
if ($ShowISP =~ /P/i) { print "$Message[56] | "; }
if ($ShowISP =~ /P/i) { print "$Message[15] | "; }
if ($ShowISP =~ /H/i) { print "$Message[57] | "; }
if ($ShowISP =~ /H/i) { print "$Message[15] | "; }
if ($ShowISP =~ /B/i) { print "$Message[75] | "; }
if ($ShowISP =~ /L/i) { print "$Message[9] | "; }
print "
\n";
$total_p=$total_h=$total_k=0;
my $count=0;
&BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Org'},\%_org_h,\%_org_h);
foreach my $key (@keylist) {
if ($key eq 'unknown') { next; }
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int($_org_p{$key}/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($_org_h{$key}/$TotalHits*1000)/10; }
print "";
my $org=$key; $org =~ s/_/ /g;
print "".ucfirst($org)." | ";
if ($ShowISP =~ /P/i) { print "".($_org_p{$key}?Format_Number($_org_p{$key}):" ")." | "; }
if ($ShowISP =~ /P/i) { print "".($_org_p{$key}?"$p_p %":' ')." | "; }
if ($ShowISP =~ /H/i) { print "".($_org_h{$key}?Format_Number($_org_h{$key}):" ")." | "; }
if ($ShowISP =~ /H/i) { print "".($_org_h{$key}?"$p_h %":' ')." | "; }
if ($ShowISP =~ /B/i) { print "".Format_Bytes($_org_k{$key})." | "; }
if ($ShowISP =~ /L/i) { print "".($_org_p{$key}?Format_Date($_org_l{$key},1):'-')." | "; }
print "
\n";
$total_p += $_org_p{$key}||0;
$total_h += $_org_h{$key};
$total_k += $_org_k{$key}||0;
$count++;
}
if ($Debug) { debug("Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h",2); }
$rest_p=0;
$rest_h=$TotalHits-$total_h;
$rest_k=0;
if ($rest_p > 0 || $rest_h > 0 || $rest_k > 0) { # All other cities
# print "";
# print " | ";
# if ($ShowISP =~ /P/i) { print " | "; }
# if ($ShowISP =~ /P/i) { print " | "; }
# if ($ShowISP =~ /H/i) { print " | "; }
# if ($ShowISP =~ /H/i) { print " | "; }
# if ($ShowISP =~ /B/i) { print " | "; }
# if ($ShowISP =~ /L/i) { print " | "; }
# print "
\n";
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int($rest_p/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($rest_h/$TotalHits*1000)/10; }
print "";
print "$Message[2]/$Message[0] | ";
if ($ShowISP =~ /P/i) { print "".($rest_p?Format_Number($rest_p):" ")." | "; }
if ($ShowISP =~ /P/i) { print "".($rest_p?"$p_p %":' ')." | "; }
if ($ShowISP =~ /H/i) { print "".($rest_h?Format_Number($rest_h):" ")." | "; }
if ($ShowISP =~ /H/i) { print "".($rest_h?"$p_h %":' ')." | "; }
if ($ShowISP =~ /B/i) { print "".Format_Bytes($rest_k)." | "; }
if ($ShowISP =~ /L/i) { print " | "; }
print "
\n";
}
&tab_end();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: ShowInfoHost_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to add additionnal columns to the Hosts report.
# This function is called when building rows of the report (One call for each
# row). So it allows you to add a column in report, for example with code :
# print "This is a new cell for $param | ";
# Parameters: Host name or ip
#-----------------------------------------------------------------------------
sub ShowInfoHost_geoip_org_maxmind {
my $param="$_[0]";
# <-----
if ($param eq '__title__') {
my $NewLinkParams=${QueryString};
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)output(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
my $NewLinkTarget='';
if ($DetailedReportsOnNewWindows) { $NewLinkTarget=" target=\"awstatsbis\""; }
if (($FrameName eq 'mainleft' || $FrameName eq 'mainright') && $DetailedReportsOnNewWindows < 2) {
$NewLinkParams.="&framename=mainright";
$NewLinkTarget=" target=\"mainright\"";
}
$NewLinkParams =~ s/(&|&)+/&/i;
$NewLinkParams =~ s/^&//; $NewLinkParams =~ s/&$//;
if ($NewLinkParams) { $NewLinkParams="${NewLinkParams}&"; }
print "";
print "GeoIP Org";
print " | ";
}
elsif ($param) {
my $ip=0;
my $key;
if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
$ip=4;
$key=$param;
}
elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address
$ip=6;
$key=$param;
}
print "";
if ($key && $ip==4) {
my $org = TmpLookup_geoip_org_maxmind($param);
if (!$org && $type eq 'geoippureperl')
{
# Function org_by_addr does not exists in PurePerl but org_by_name do same
$org=$geoip_org_maxmind->org_by_name($param) if $geoip_org_maxmind;
}
elsif(!$org)
{
$org=$geoip_org_maxmind->org_by_addr($param) if $geoip_org_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetOrgByIp for $param: [$org]",5); }
if ($org) {
if (length($org) <= $MAXLENGTH) {
print "$org";
}
else {
print substr($org,0,$MAXLENGTH).'...';
}
}
else { print "$Message[0]"; }
}
if ($key && $ip==6) {
print "$Message[0]";
}
if (! $key) {
my $org = TmpLookup_geoip_org_maxmind($param);
if (!$org && $type eq 'geoippureperl')
{
$org=$geoip_org_maxmind->org_by_name($param) if $geoip_org_maxmind;
}
elsif(!$org)
{
$org=$geoip_org_maxmind->org_by_name($param) if $geoip_org_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetOrgByHostname for $param: [$org]",5); }
if ($org) {
if (length($org) <= $MAXLENGTH) {
print "$org";
}
else {
print substr($org,0,$MAXLENGTH).'...';
}
}
else { print "$Message[0]"; }
}
print " | ";
}
else {
print " | ";
}
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionInitHashArray_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionInitHashArray_geoip_org_maxmind {
# my $param="$_[0]";
# <-----
if ($Debug) { debug(" Plugin $PluginName: Init_HashArray"); }
%_org_p = %_org_h = %_org_k = %_org_l =();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessIP_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessIp_geoip_org_maxmind {
my $param="$_[0]"; # Param must be an IP
# <-----
my $org = TmpLookup_geoip_org_maxmind($param);
if (!$org && $type eq 'geoippureperl')
{
# Function org_by_addr does not exists in PurePerl but org_by_name do same
$org=$geoip_org_maxmind->org_by_name($param) if $geoip_org_maxmind;
}
elsif(!$org)
{
$org=$geoip_org_maxmind->org_by_addr($param) if $geoip_org_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetOrgByIp for $param: [$org]",5); }
if ($org) {
$org =~ s/\s/_/g;
$_org_h{$org}++;
} else {
$_org_h{'unknown'}++;
}
# if ($timerecord > $_org_l{$city}) { $_org_l{$city}=$timerecord; }
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessHostname_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessHostname_geoip_org_maxmind {
my $param="$_[0]"; # Param must be an IP
# <-----
my $org = TmpLookup_geoip_org_maxmind($param);
if (!$org && $type eq 'geoippureperl')
{
$org=$geoip_org_maxmind->org_by_name($param) if $geoip_org_maxmind;
}
elsif(!$org)
{
$org=$geoip_org_maxmind->org_by_name($param) if $geoip_org_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetOrgByHostname for $param: [$org]",5); }
if ($org) {
$org =~ s/\s/_/g;
$_org_h{$org}++;
} else {
$_org_h{'unknown'}++;
}
# if ($timerecord > $_org_l{$city}) { $_org_l{$city}=$timerecord; }
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionReadHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionReadHistory_geoip_org_maxmind {
my $issectiontoload=shift;
my $xmlold=shift;
my $xmleb=shift;
my $countlines=shift;
# <-----
if ($Debug) { debug(" Plugin $PluginName: Begin of PLUGIN_$PluginName section"); }
my @field=();
my $count=0;my $countloaded=0;
do {
if ($field[0]) {
$count++;
if ($issectiontoload) {
$countloaded++;
if ($field[2]) { $_org_h{$field[0]}+=$field[2]; }
}
}
$_=;
chomp $_; s/\r//;
@field=split(/\s+/,($xmlold?XMLDecodeFromHisto($_):$_));
$countlines++;
}
until ($field[0] eq "END_PLUGIN_$PluginName" || $field[0] eq "${xmleb}END_PLUGIN_$PluginName" || ! $_);
if ($field[0] ne "END_PLUGIN_$PluginName" && $field[0] ne "${xmleb}END_PLUGIN_$PluginName") { error("History file is corrupted (End of section PLUGIN not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).","","",1); }
if ($Debug) { debug(" Plugin $PluginName: End of PLUGIN_$PluginName section ($count entries, $countloaded loaded)"); }
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionWriteHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionWriteHistory_geoip_org_maxmind {
my ($xml,$xmlbb,$xmlbs,$xmlbe,$xmlrb,$xmlrs,$xmlre,$xmleb,$xmlee)=(shift,shift,shift,shift,shift,shift,shift,shift,shift);
if ($Debug) { debug(" Plugin $PluginName: SectionWriteHistory_$PluginName start - ".(scalar keys %_org_h)); }
# <-----
print HISTORYTMP "\n";
if ($xml) { print HISTORYTMP "$MAXNBOFSECTIONGIR\n"; }
print HISTORYTMP "# Plugin key - Pages - Hits - Bandwidth - Last access\n";
#print HISTORYTMP "# The $MaxNbOfExtra[$extranum] first number of hits are first\n";
$ValueInFile{'plugin_geoip_org_maxmind'}=tell HISTORYTMP;
print HISTORYTMP "${xmlbb}BEGIN_PLUGIN_$PluginName${xmlbs}".(scalar keys %_org_h)."${xmlbe}\n";
&BuildKeyList($MAXNBOFSECTIONGIR,1,\%_org_h,\%_org_h);
my %keysinkeylist=();
foreach (@keylist) {
$keysinkeylist{$_}=1;
#my $page=$_org_p{$_}||0;
#my $bytes=$_org_k{$_}||0;
#my $lastaccess=$_org_l{$_}||'';
print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_org_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
foreach (keys %_org_h) {
if ($keysinkeylist{$_}) { next; }
#my $page=$_org_p{$_}||0;
#my $bytes=$_org_k{$_}||0;
#my $lastaccess=$_org_l{$_}||'';
print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_org_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
print HISTORYTMP "${xmleb}END_PLUGIN_$PluginName${xmlee}\n";
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: LoadOverrideFile
# Attempts to load a comma delimited file that will override the GeoIP database
# Useful for Intranet records
# CSV format: IP,"organization"
#-----------------------------------------------------------------------------
sub LoadOverrideFile_geoip_org_maxmind{
my $filetoload="";
if ($OverrideFile){
if (!open(GEOIPFILE, $OverrideFile)){
debug("Plugin $PluginName: Unable to open override file: $OverrideFile");
$LoadedOverride = 1;
return;
}
}else{
my $conf = (exists(&Get_Config_Name) ? Get_Config_Name() : $SiteConfig);
if ($conf && open(GEOIPFILE,"$DirData/$PluginName.$conf.txt")) { $filetoload="$DirData/$PluginName.$conf.txt"; }
elsif (open(GEOIPFILE,"$DirData/$PluginName.txt")) { $filetoload="$DirData/$PluginName.txt"; }
else { debug("No override file \"$DirData/$PluginName.txt\": $!"); }
}
if ($filetoload)
{
# This is the fastest way to load with regexp that I know
while (){
chomp $_;
s/\r//;
my @record = split(",", $_);
# replace quotes if they were used in the file
foreach (@record){ $_ =~ s/"//g; }
# store in hash
$TmpDomainLookup{$record[0]} = $record[1];
}
close GEOIPFILE;
debug(" Plugin $PluginName: Overload file loaded: ".(scalar keys %TmpDomainLookup)." entries found.");
}
$LoadedOverride = 1;
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: TmpLookup
# Searches the temporary hash for the parameter value and returns the corresponding
# GEOIP entry
#-----------------------------------------------------------------------------
sub TmpLookup_geoip_org_maxmind(){
$param = shift;
if (!$LoadedOverride){&LoadOverrideFile_geoip_org_maxmind();}
#my $val;
#if ($geoip_org_maxmind &&
#(($type eq 'geoip' && $geoip_org_maxmind->VERSION >= 1.30) ||
# $type eq 'geoippureperl' && $geoip_org_maxmind->VERSION >= 1.17)){
# $val = $TmpDomainLookup{$geoip_org_maxmind->get_ip_address($param)};
#}
#else {$val = $TmpDomainLookup{$param};}
#return $val || '';
return $TmpDomainLookup{$param}||'';
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/timezone.pm 0000640 0001750 0001750 00000016125 12410217071 017573 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# TimeZone AWStats reloaded plugin
#
# Allow AWStats to convert GMT time stamps to local time zone
# taking into account daylight saving time.
# If the POSIX module is available, a target time zone name
# can be provided, otherwise the default system local time is used.
# For compatibility with the original version of this plugin, "-/+hours"
# is interpreted as a fixed difference to GMT.
#
# 2009 jacob@internet24.de
#-----------------------------------------------------------------------------
# Perl Required Modules: POSIX
#-----------------------------------------------------------------------------
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !!!!! This plugin reduces AWStats speed by about 10% !!!!!
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
# ----->
use strict;no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="5.1";
my $PluginHooksFunctions="ChangeTime GetTimeZoneTitle";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$PluginTimeZoneZone
$PluginTimeZoneCache
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_timezone {
my $InitParams=shift;
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
if ($InitParams)
{
if (!eval ('require "POSIX.pm"'))
{
return $@?"Error: $@":"Error: Need Perl module POSIX";
}
}
$PluginTimeZoneZone = "$InitParams";
$PluginTimeZoneCache = {};
# ----->
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: ChangeTime_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
#-----------------------------------------------------------------------------
sub ChangeTime_timezone {
my @d = @{$_[0]};
my $e = $PluginTimeZoneCache->{$d[2]};
my ($i);
unless ($e) {
$e = $PluginTimeZoneCache->{$d[2]} = [
tz_find_zone_diff($PluginTimeZoneZone, $d[2]),
tz_find_month_length($PluginTimeZoneZone, $d[2])
]
}
INTERVAL: foreach $i (@{@$e[0]}) {
foreach (1,0,3,4,5) {
next INTERVAL if $d[$_]>@$i[$_];
last if $d[$_]<@$i[$_];
}
$d[5] += @$i[8];
if ( $d[5]<0 ) {
$d[5] += 60, $d[4]--;
} elsif ( $d[5]>59 ) {
$d[5] -= 60, $d[4]++;
}
$d[4] += @$i[7];
if ( $d[4]<0 ) {
$d[4] += 60, $d[3]--;
} elsif ( $d[4]>59 ) {
$d[4] -= 60, $d[3]++;
}
$d[3] += @$i[6];
if ( $d[3]<0 ) {
$d[3] += 24, $d[0]--;
} elsif ( $d[3]>23 ) {
$d[3] -= 24, $d[0]++;
} else {
return @d;
}
if ($d[0]<1) {
$d[1]--;
if ( $d[1]<1 ) {
$d[2]--, $d[1] = 12, $d[0] = 31;
} else {
$d[0] = $e->[1][$d[1]];
}
} elsif ($d[0]>$e->[1][$d[1]]) {
$d[1]++, $d[0]=1;
if ( $d[1]>12 ) {
$d[2]++, $d[1] = 1;
}
}
return @d;
}
# This should never be reached
return @d;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetTimeZoneTitle_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
#-----------------------------------------------------------------------------
sub GetTimeZoneTitle_timezone {
return $PluginTimeZoneZone;
}
#-----------------------------------------------------------------------------
# Tools
#-----------------------------------------------------------------------------
# convenience wrappers
sub tz_mktime
{
return timegm($_[0], $_[1], $_[2],
$_[3], $_[4]-1, $_[5]-1900, 0, 0, -1);
}
sub tz_interval
{
my ($time, $shift) = @_;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
gmtime($time);
return [
$mday,
$mon+1,
2147483647, # max(int32)
$hour,
$min,
$sec,
int($shift/3600),
int(($shift%3600)/60),
int(($shift%60)),
]
}
# return largest $value between $left and $right
# whose tz_shift is equal to that of $left
sub tz_find_break
{
my ($left, $right) = @_;
return undef if $left>$right;
return $left if ($right-$left)<=1;
my $middle = int(($right+$left)/2);
my ($leftshift, $rightshift, $middleshift) =
(tz_shift($left), tz_shift($right), tz_shift($middle));
if ($leftshift == $middleshift) {
return undef if $rightshift == $middleshift;
return tz_find_break($middle, $right);
}
elsif ($rightshift == $middleshift) {
return tz_find_break($left, $middle);
}
}
# compute difference beetween localtime and gmtime in seconds
# for unix time stamp $time
sub tz_shift
{
my ($time) = @_;
my ($lsec,$lmin,$lhour,$lmday,$lmon,$lyear,$lwday,$lyday,$lisdst) =
localtime($time);
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
gmtime($time);
my $day_change = $lyear-$year;
$day_change = $lmon-$mon unless $day_change;
$day_change = $lmday-$mday unless $day_change;
my $hour_diff = $lhour-$hour;
my $min_diff = $lmin-$min;
my $sec_diff = $lsec-$sec;
if ($day_change>0) {
$hour_diff +=24;
}
elsif($day_change<0) {
$hour_diff -=24;
}
return (($hour_diff*60)+$min_diff)*60+$sec_diff;
}
# Compute time zone shift intervals for $year
# and time zone $zone
sub tz_find_zone_diff
{
my ($zone, $year) = @_;
my $othertz = $PluginTimeZoneZone &&
$PluginTimeZoneZone !~ m/^[+-]?\d+$/;
my ($left, $middle, $right);
my ($leftshift, $middleshift, $rightshift);
{
local $ENV{TZ} = $zone
if $othertz;
$left = tz_mktime(0,0,0,1,1,$year);
$middle = tz_mktime(0,0,0,1,7,$year);
$right = tz_mktime(59,59,23,31,12,$year);
if (!$PluginTimeZoneZone || $PluginTimeZoneZone !~ m/^[+-]?\d+$/)
{
$leftshift = tz_shift($left);
$middleshift = tz_shift($middle);
$rightshift = tz_shift($right)
}
else
{
$leftshift = $middleshift = $rightshift =
int($PluginTimeZoneZone)*3600;
}
if ($leftshift != $rightshift || $rightshift != $middleshift) {
return
[
tz_interval(tz_find_break($left, $middle), $leftshift),
tz_interval(tz_find_break($middle, $right), $middleshift),
tz_interval($right, $rightshift)
]
}
POSIX::tzset() if $othertz;
}
POSIX::tzset() if $othertz;
return [ tz_interval($right, $rightshift) ]
}
# Compute number of days in all months for $year
sub tz_find_month_length
{
my ($zone, $year) = @_;
my $othertz = $PluginTimeZoneZone &&
$PluginTimeZoneZone !~ m/^[+-]?\d+$/;
my $months = [ undef, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 ];
{
local $ENV{TZ} = $zone
if $othertz;
# leap year?
$months->[2] = 29 if
(localtime(tz_mktime(0, 0, 12, 28, 2, $year)+86400))[4]
== 1;
POSIX::tzset() if $othertz;
}
POSIX::tzset() if $othertz;
return $months;
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/ipv6.pm 0000640 0001750 0001750 00000004577 12410217071 016635 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# IPv6 AWStats plugin
# This plugin allow AWStats to make reverse DNS Lookup on IPv6 addresses.
#-----------------------------------------------------------------------------
# Perl Required Modules: Net::IP and Net::DNS
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
if (!eval ('require "Net/IP.pm";')) { return $@?"Error: $@":"Error: Need Perl module Net::IP"; }
if (!eval ('require "Net/DNS.pm";')) { return $@?"Error: $@":"Error: Need Perl module Net::DNS"; }
# ----->
use strict;no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="5.5";
my $PluginHooksFunctions="GetResolvedIP";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$resolver
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_ipv6 {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin ipv6: InitParams=$InitParams",1);
$resolver = Net::DNS::Resolver->new;
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetResolvedIP_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# GetResolvedIP is called to resolve an IPv6 address into a host name
#-----------------------------------------------------------------------------
sub GetResolvedIP_ipv6 {
# <-----
my $ip = new Net::IP($_[0]);
my $reverseip= $ip->reverse_ip();
my $query = $resolver->query($reverseip, "PTR");
if (! defined($query)) { return; }
my @result=split(/\s/, ($query->answer)[0]->string);
chop($result[4]); # Remove the trailing dot of the answer.
return $result[4];
# ----->
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/graphgooglechartapi.pm 0000640 0001750 0001750 00000045643 12410217071 021762 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# GraphGoogleChartApi AWStats plugin
# Allow AWStats to replace bar graphs with a Google Graph image
#-----------------------------------------------------------------------------
# Perl Required Modules: None
#-----------------------------------------------------------------------------
#
# Changelog
#
# 1.0 - Initial release by george@dynapres.nl
# 1.1 - Changed scaling: making it independent of chart series
# 1.2 - Added pie charts, visualization hook, map and axis labels by Chris Larsen
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion = "7.0";
my $PluginHooksFunctions = "Init ShowGraph AddHTMLHeader";
my $PluginName = "graphgooglechartapi";
my $ChartProtocol = "https://";
my $ChartURI = "chart.googleapis.com/chart?"; # Don't put the HTTP part here!
my $ChartIndex = 0;
my $title;
my $type;
my $imagewidth = 640; # maximum image width.
my $imageratio = .25; # Height is defaulted to 25% of width
my $pieratio = .20; # Height for pie charts should be different
my $mapratio = .62; # Height for maps is different
my $labellength;
my @blocklabel = ();
my @vallabel = ();
my @valcolor = ();
my @valmax = ();
my @valtotal = ();
my @valaverage = ();
my @valdata = ();
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$DirClasses
$URLIndex
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_graphgooglechartapi {
my $InitParams = shift;
my $checkversion = &Check_Plugin_Version($PluginNeedAWStatsVersion);
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
$DirClasses = $InitParams;
# ----->
$title = "";
$type = "";
$labellength=2;
$ChartIndex = -1;
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-------------------------------------------------------
# PLUGIN FUNCTION: ShowGraph_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# Prints the proper chart depending on the $type provided
# Parameters: $title $type $imagewidth \@blocklabel,\@vallabel,\@valcolor,\@valmax,\@valtotal
# Input: None
# Output: HTML code for awgraphapplet insertion
# Return: 0 OK, 1 Error
#-------------------------------------------------------
sub ShowGraph_graphgooglechartapi() {
$title = shift;
$type = shift;
$imagewidth = shift || 640;
$blocklabel = shift;
$vallabel = shift;
$valcolor = shift;
$valmax = shift;
$valtotal = shift;
$valaverage = shift;
$valdata = shift;
# check width
if ($imagewidth < 1){$imagewidth=640;}
if ($type eq 'month') {
$labellength=3;
print Get_Img_Tag(Graph_Monthly(), $title);
}
elsif ($type eq 'daysofmonth') {
$labellength=2;
print Get_Img_Tag(Graph_Daily(), $title);
}
elsif ($type eq 'daysofweek') {
$labellength=3;
print Get_Img_Tag(Graph_Weekly(), $title);
}
elsif ($type eq 'hours') {
$labellength=2;
print Get_Img_Tag(Graph_Hourly(), $title);
}
elsif ($type eq 'cluster'){
$labellength=32;
print Get_Img_Tag(Graph_Pie(), $title);
}
elsif ($type eq 'filetypes'){
$labellength=4;
print Get_Img_Tag(Graph_Pie(), $title);
}
elsif ($type eq 'httpstatus'){
$labellength=4;
print Get_Img_Tag(Graph_Pie(), $title);
}
elsif ($type eq 'browsers'){
$labellength=32;
print Get_Img_Tag(Graph_Pie(), $title);
}
elsif ($type eq 'downloads'){
$labellength=32;
print Get_Img_Tag(Graph_Pie(), $title);
}
elsif ($type eq 'pages'){
$labellength=32;
print Get_Img_Tag(Graph_Pie(), $title);
}
elsif ($type eq 'oss'){
$labellength=32;
print Get_Img_Tag(Graph_Pie(), $title);
}
elsif ($type eq 'hosts'){
$labellength=32;
print Get_Img_Tag(Graph_Pie(), $title);
}
elsif ($type eq 'countries_map'){
print Chart_Map();
}
else {
debug("Unknown type parameter in ShowGraph_graphgooglechartapi function: $title",1);
#error("Unknown type parameter in ShowGraph_graphgooglechartapi function");
}
return 0;
}
#-------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLHeader_pluginname
# UNIQUE: NO
# Prints javascript includes for Google Visualizations
# Parameters: None
# Input: None
# Output: HTML code for Google Visualizations
# Return: 0 OK, 1 Error
#-------------------------------------------------------
sub AddHTMLHeader_graphgooglechartapi(){
print "\n";
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Graph_Monthly
# Prints the image code to display a column chart of monthly usage
# Parameters: None
# Input: None
# Output: HTML code to print a chart
# Return: 0 OK, 1 Error
#-------------------------------------------------------
sub Graph_Monthly(){
my $chxt = "chxt=";
my $chxl = "chxl=";
my $chxs = "chxs=";
my $chco = "chco=";
my $chg = "chg=";
my $chs = "chs=";
my $cht = "cht=bvg";
my $chd = "chd=t:";
my $cba = "chbh=a"; # shows the whole month
my $graphwidth = $imagewidth;
my $graphheight = int ($imagewidth * $imageratio);
# round max values
foreach my $i(0..(scalar @$valmax)){
@$valmax[$i] = Round_Up(@$valmax[$i]);
}
# setup axis
$chxt .= "x,y,y,r"; # add an x for years
# get the month labels
$chxl .= "0:|";
$chxl .= Get_Labels();
# get the hits/pages max
$chxl .= "1:|0|".Get_Suffixed((@$valmax[0]/2),0)."|".Get_Suffixed(@$valmax[0],0)."|";
# get the visitors/pages max
$chxl .= "2:|0|".Get_Suffixed((@$valmax[2]/2),0)."|".Get_Suffixed(@$valmax[2],0)."|";
# get bytes
$chxl .= "3:|0|".Get_Suffixed((@$valmax[4]/2),1)."|".Get_Suffixed(@$valmax[4],1);
# TODO add the year at the start and end
# set the axis colors
$chxs .= "1,".@$valcolor[0]."|2,".@$valcolor[2]."|3,".@$valcolor[4];
# dump colors
foreach my $i(0..(scalar @$valcolor)){
$chco .= @$valcolor[$i];
if ($i < (scalar @$valcolor)-1){ $chco .= ",";}
}
# grid lines
$chg .= "0,50";
# size
$chs .= $graphwidth."x".$graphheight;
# finally get the data
$chd .= Get_Column_Data();
# string and dump
return "$cht&$chxl&$chxt&$chxs&$chco&$chg&$chs&$chd&$cba";
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Graph_Daily
# Prints the image code to display a column chart of daily usage
# Parameters: None
# Input: None
# Output: HTML code to print a chart
# Return: 0 OK, 1 Error
#-------------------------------------------------------
sub Graph_Daily(){
my $chxt = "chxt=";
my $chxl = "chxl=";
my $chxs = "chxs=";
my $chco = "chco=";
my $chg = "chg=";
my $chs = "chs=";
my $cht = "cht=bvg";
my $chd = "chd=t:";
my $cba = "chbh=a"; # shows the whole month
my $graphwidth = $imagewidth;
my $graphheight = int ($imagewidth * $imageratio);
# round max values
foreach my $i(0..(scalar @$valmax)){
@$valmax[$i] = Round_Up(@$valmax[$i]);
}
# setup axis
$chxt .= "x,y,y,r"; # add an x for years
# setup axis labels
# get day labels
$chxl .= "0:|";
$chxl .= Get_Labels();
# get the hits/pages max
$chxl .= "1:|0|".Get_Suffixed((@$valmax[0]/2),0)."|".Get_Suffixed(@$valmax[0],0)."|";
# get the visitors/pages max
$chxl .= "2:|0|".Get_Suffixed((@$valmax[1]/2),0)."|".Get_Suffixed(@$valmax[1],0)."|";
# get bytes
$chxl .= "3:|0|".Get_Suffixed((@$valmax[3]/2),1)."|".Get_Suffixed(@$valmax[3],1);
# TODO month name
# set the axis colors
$chxs .= "1,".@$valcolor[0]."|2,".@$valcolor[1]."|3,".@$valcolor[3];
# dump colors
foreach my $i(0..(scalar @$valcolor)){
$chco .= @$valcolor[$i];
if ($i < (scalar @$valcolor)-1){ $chco .= ",";}
}
# grid lines
$chg .= "0,50";
# size
$chs .= $graphwidth."x".$graphheight;
# finally get the data
$chd .= Get_Column_Data();
# string and dump
return "$cht&$chxl&$chxt&$chxs&$chco&$chg&$chs&$chd&$cba";
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Graph_Weekly
# Prints the image code to display a column chart of weekly usage
# Parameters: None
# Input: None
# Output: HTML code to print a chart
# Return: 0 OK, 1 Error
#-------------------------------------------------------
sub Graph_Weekly(){
my $chxt = "chxt=";
my $chxl = "chxl=";
my $chxs = "chxs=";
my $chco = "chco=";
my $chg = "chg=";
my $chs = "chs=";
my $cht = "cht=bvg";
my $chd = "chd=t:";
my $cba = "chbh=a"; # shows the whole month
my $graphwidth = int ($imagewidth * .75); # to maintain old look/ratio, reduce width of the weekly
my $graphheight = int ($imagewidth * $imageratio);
# round max values
foreach my $i(0..(scalar @$valmax)){
@$valmax[$i] = Round_Up(@$valmax[$i]);
}
# setup axis
$chxt .= "x,y,y,r"; # add an x for years
# setup axis labels
# get the day labels
$chxl .= "0:|";
$chxl .= Get_Labels();
# get the hits/pages max
$chxl .= "1:|0|".Get_Suffixed((@$valmax[0]/2),0)."|".Get_Suffixed(@$valmax[0],0)."|";
# get the visitors/pages max
$chxl .= "2:|0|".Get_Suffixed((@$valmax[1]/2),0)."|".Get_Suffixed(@$valmax[1],0)."|";
# get bytes
$chxl .= "3:|0|".Get_Suffixed((@$valmax[2]/2),1)."|".Get_Suffixed(@$valmax[2],1);
# set the axis colors
$chxs .= "1,".@$valcolor[0]."|2,".@$valcolor[1]."|3,".@$valcolor[2];
# dump colors
foreach my $i(0..(scalar @$valcolor)){
$chco .= @$valcolor[$i];
if ($i < (scalar @$valcolor)-1){ $chco .= ",";}
}
# grid lines
$chg .= "0,50";
# size
$chs .= $graphwidth."x".$graphheight;
# finally get the data
$chd .= Get_Column_Data();
# string and dump
return "$cht&$chxl&$chxt&$chxs&$chco&$chg&$chs&$chd&$cba";
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Graph_Hourly
# Prints the image code to display a column chart of hourly usage
# Parameters: None
# Input: None
# Output: HTML code to print a chart
# Return: 0 OK, 1 Error
#-------------------------------------------------------
sub Graph_Hourly(){
my $chxt = "chxt=";
my $chxl = "chxl=";
my $chxs = "chxs=";
my $chco = "chco=";
my $chg = "chg=";
my $chs = "chs=";
my $cht = "cht=bvg";
my $chd = "chd=t:";
my $cba = "chbh=a"; # shows the whole month
my $graphwidth = $imagewidth;
my $graphheight = int ($imagewidth * $imageratio);
# round max values
foreach my $i(0..(scalar @$valmax - 1)){
@$valmax[$i] = Round_Up(@$valmax[$i]);
}
# setup axis
$chxt .= "x,y,y,r"; # add an x for years
# setup axis labels
$chxl .= "0:|";
$chxl .= Get_Labels();
# get the hits/pages max
$chxl .= "1:|0|".Get_Suffixed((@$valmax[0]/2),0)."|".Get_Suffixed(@$valmax[0],0)."|";
# get the visitors/pages max
$chxl .= "2:|0|".Get_Suffixed((@$valmax[1]/2),0)."|".Get_Suffixed(@$valmax[1],0)."|";
# get bytes
$chxl .= "3:|0|".Get_Suffixed((@$valmax[2]/2),1)."|".Get_Suffixed(@$valmax[2],1);
# TODO years
# set the axis colors
$chxs .= "1,".@$valcolor[0]."|2,".@$valcolor[1]."|3,".@$valcolor[2];
# dump colors
foreach my $i(0..(scalar @$valcolor)){
$chco .= @$valcolor[$i];
if ($i < (scalar @$valcolor)-1){ $chco .= ",";}
}
# grid lines
$chg .= "0,50";
# size
$chs .= $graphwidth."x".$graphheight;
# finally get the data
$chd .= Get_Column_Data();
# string and dump
return "$cht&$chxl&$chxt&$chxs&$chco&$chg&$chs&$chd&$cba";
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Graph_Pie
# Prints the image code to display a pie chart of the provided data
# Parameters: None
# Input: None
# Output: HTML code to print a chart
# Return: 0 OK, 1 Error
#-------------------------------------------------------
sub Graph_Pie(){
my $chl = "chl=";
my $chs = "chs=";
my $chco = "chco=";
my $cht = "cht=p3";
my $chd = "chd=t:";
my $graphwidth = $imagewidth;
my $graphheight = int ($imagewidth * $pieratio);
# get labels
$chl .= Get_Labels();
# get data, just read off the array for however many labels we have
foreach my $i (0..((scalar @$blocklabel)-1)) {
$chd .= int(@$valdata[$i]);
$chd .= ($i < ((scalar @$blocklabel)-1) ? "," : "");
}
# get color, just the first color passed
$chco .= @$valcolor[0];
# set size
$chs .= $graphwidth."x".$graphheight;
return "$cht&$chs&$chco&$chl&$chd";
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Chart_Map
# Prints a Javascript and DIV tag to display a Google Visualization GeoMap
# that uses the Flash plugin to display a map of the world shaded to reflect
# the provided data
# Parameters: None
# Input: None
# Output: Javascript and DIV tag
# Return: 0 OK, 1 Error
#-------------------------------------------------------
sub Chart_Map(){
my $graphwidth = $imagewidth;
my $graphheight = int ($imagewidth * $mapratio);
# Assume we've already included the proper headers so just call our script inline
print "\n\n";
# print the div tag that will contain the map
print "\n";
return;
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Get_Column_Data
# Loops through the data array and prints a CHD string to send to a Google
# chart via the API
# Parameters: None
# Input: @valcolor, @blocklabel, @valdata, @valmax
# Output: None
# Return: A pipe delimited string of data. REQUIRES the "chd=t:" prepended
#-------------------------------------------------------
# Returns a string with the CHD data
sub Get_Column_Data(){
my $chd = "";
# use the # of colors to determine how many values we have
$x= scalar @$valcolor;
for ($serie = 0; $serie <= $x; $serie++) {
foreach my $j (1.. (scalar @$blocklabel)) {
if ($j > 1) { $chd .= ","; }
$val = @$valdata[($j-1)*$x+$serie];
# convert our values to a percent of max
$chd .= (@$valmax[$serie] > 0 ? int(($val / Round_Up(@$valmax[$serie])) * 100) : 0);
}
if ($serie < $x) {
$chd .= "|";
}
}
# return
return $chd;
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Get_Labels
# Returns a CHXL string with labels to send to the Google chart API. Long labels
# are shortened to $labellength
# TODO - better shortening method instead of just lopping off the end of strings
# Parameters: None
# Input: @blocklabel, $labellength
# Output: None
# Return: A pipe delimited string of labels. REQUIRES the "chxl=" prepended
#-------------------------------------------------------
sub Get_Labels(){
my $chxl = "";
foreach my $i (1..(scalar @$blocklabel)) {
$temp = @$blocklabel[$i-1];
if (length($temp) > $labellength){
$temp = (substr($temp,0,$labellength));
}
$chxl .= "$temp|";
}
$chxl =~ s/&//;
return $chxl;
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Round_Up
# Rounds a number up to the next most significant digit, i.e. 1234 becomes 2000
# Useful for getting the max values of our graph
# Parameters: $num
# Input: None
# Output: None
# Return: The rounded number
#-------------------------------------------------------
sub Round_Up(){
my $num = shift;
$num = int($num);
if ($num < 1){ return $num; }
# under 100, just increment and dump
if ($num < 100){return $num++; }
$i = int(substr($num,0,2))+1;
# pad with 0s
$l = length($i);
while ($l<(length($num))){
$i .= "0";
$l++;
}
return $i;
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Get_Suffixed
# Converts a number for axis labels and appends the scientific notation suffix
# or proper size in bytes
# Parameters: $num
# Input: @Message array from AWStats
# Output: None
# Return: A number with suffix, i.e. 400 MB or 200 K
#-------------------------------------------------------
sub Get_Suffixed(){
my $num = shift || 0;
my $isbytes = shift || 0;
my $float = 0;
if ( $num >= ( 1 << 30 ) ) {
$float = (split(/\./, $num / 1000000000))[1];
if ($float){
return sprintf( "%.1f", $num / 1000000000 ) . ($isbytes ? " $Message[110]" : " B");
}else{
return sprintf( "%.0f", $num / 1000000000 ) . ($isbytes ? " $Message[110]" : " B");
}
}
if ( $num >= ( 1 << 20 ) ) {
$float = (split(/\./, $num / 1000000))[1];
if ($float){
return sprintf( "%.1f", $num / 1000000 ) . ($isbytes ? " $Message[109]" : " M");
}else{
return sprintf( "%.0f", $num / 1000000 ) . ($isbytes ? " $Message[109]" : " M");
}
}
if ( $num >= ( 1 << 10 ) ) {
$float = (split(/\./, $num / 1000))[1];
if ($float){
return sprintf( "%.1f", $num / 1000 ) . ($isbytes ? " $Message[108]" : " K");
}else{
return sprintf( "%.0f", $num / 1000 ) . ($isbytes ? " $Message[108]" : " K");
}
}
return int($num);
}
#-------------------------------------------------------
# PLUGIN FUNCTION: Get_Img_Tag
# Builds the full IMG tag to place in HTML that will call the Google Charts API
# Parameters: $params, $title
# Input: $ChartProtocol, $ChartURI, $ChartIndex
# Output: None
# Return: An HTML IMG tag
#-------------------------------------------------------
sub Get_Img_Tag(){
my $params = shift || "";
my $title = shift || "";
my $tag = "
= 9 ? 0 : $ChartIndex + 1);
$tag .= $params;
$tag .= "\" alt=\"$title\"/>";
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/decodeutfkeys.pm 0000640 0001750 0001750 00000005514 12410217071 020577 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# decodeUTFKeys AWStats plugin
# Allow AWStats to convert keywords strings coded by some search engines in
# UTF8 coding to a common string in a local charset.
#-----------------------------------------------------------------------------
# Perl Required Modules: Encode and URI::Escape
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
if (!eval ('require "Encode.pm"')) { return $@?"Error: $@":"Error: Need Perl module Encode"; }
if (!eval ('require "URI/Escape.pm"')) { return $@?"Error: $@":"Error: Need Perl module URI::Escape"; }
#if (!eval ('require "HTML/Entities.pm"')) { return $@?"Error: $@":"Error: Need Perl module HTML::Entities"; }
# ----->
use strict;no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="6.0";
my $PluginHooksFunctions="DecodeKey";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_decodeutfkeys {
my $InitParams=shift;
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
# ----->
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#------------------------------------------------------------------------------
# Function: Converts an UTF8 string to specified Charset
# Parameters: utfstringtodecode charsettoencode
# Return: newencodedstring
#------------------------------------------------------------------------------
sub DecodeKey_decodeutfkeys {
my $string = shift;
my $encoding = shift;
if (! $encoding) { error("Function DecodeKey from plugin decodeutfkeys was called but AWStats don't know language code required to output new value."); }
$string =~ s/\\x(\w\w)/%$1/gi; # Change "\xc4\xbe\xd7\xd3\xc3\xc0" into "%c4%be%d7%d3%c3%c0"
$string=URI::Escape::uri_unescape($string);
if ( $string =~ m/^(?:[\x00-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf])*$/ )
{
$string=Encode::encode($encoding, Encode::decode("utf-8", $string));
}
#$string=HTML::Entities::encode_entities($string);
$string =~ s/[;+]/ /g;
return $string;
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/geoip_region_maxmind.pm 0000750 0001750 0001750 00000062342 12410217071 022130 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# GeoIp_Region_Maxmind AWStats plugin
# This plugin allow you to add a region report with regions detected
# from a Geographical database (US and Canada).
# Need the licensed region database from Maxmind.
#-----------------------------------------------------------------------------
# Perl Required Modules: Geo::IP or Geo::IP::PurePerl
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
use vars qw/ $type /;
$type='geoip';
if (!eval ('require "Geo/IP.pm";')) {
$error1=$@;
$type='geoippureperl';
if (!eval ('require "Geo/IP/PurePerl.pm";')) {
$error2=$@;
$ret=($error1||$error2)?"Error:\n$error1$error2":"";
$ret.="Error: Need Perl module Geo::IP or Geo::IP::PurePerl";
return $ret;
}
}
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="6.5";
my $PluginHooksFunctions="AddHTMLMenuLink AddHTMLGraph ShowInfoHost SectionInitHashArray SectionProcessIp SectionProcessHostname SectionReadHistory SectionWriteHistory";
my $PluginName="geoip_region_maxmind";
my $LoadedOverride=0;
my $OverrideFile="";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
%TmpDomainLookup
$geoip_region_maxmind
%_region_p
%_region_h
%_region_k
%_region_l
$MAXNBOFSECTIONGIR
%region
/;
my %countrylib=('ca'=>'Canada','us'=>'USA');
my %countryregionlib=('ca'=>'Canadian Regions','us'=>'US regions');
my %regca=(
'AB',"Alberta",
'BC',"British Columbia",
'MB',"Manitoba",
'NB',"New Brunswick",
'NF',"Newfoundland",
'NS',"Nova Scotia",
'NU',"Nunavut",
'ON',"Ontario",
'PE',"Prince Edward Island",
'QC',"Quebec",
'SK',"Saskatchewan",
'NT',"Northwest Territories",
'YT',"Yukon Territory"
);
my %regus=(
'AA',"Armed Forces Americas",
'AE',"Armed Forces Europe, Middle East, & Canada",
'AK',"Alaska",
'AL',"Alabama",
'AP',"Armed Forces Pacific",
'AR',"Arkansas",
'AS',"American Samoa",
'AZ',"Arizona",
'CA',"California",
'CO',"Colorado",
'CT',"Connecticut",
'DC',"District of Columbia",
'DE',"Delaware",
'FL',"Florida",
'FM',"Federated States of Micronesia",
'GA',"Georgia",
'GU',"Guam",
'HI',"Hawaii",
'IA',"Iowa",
'ID',"Idaho",
'IL',"Illinois",
'IN',"Indiana",
'KS',"Kansas",
'KY',"Kentucky",
'LA',"Louisiana",
'MA',"Massachusetts",
'MD',"Maryland",
'ME',"Maine",
'MH',"Marshall Islands",
'MI',"Michigan",
'MN',"Minnesota",
'MO',"Missouri",
'MP',"Northern Mariana Islands",
'MS',"Mississippi",
'MT',"Montana",
'NC',"North Carolina",
'ND',"North Dakota",
'NE',"Nebraska",
'NH',"New Hampshire",
'NJ',"New Jersey",
'NM',"New Mexico",
'NV',"Nevada",
'NY',"New York",
'OH',"Ohio",
'OK',"Oklahoma",
'OR',"Oregon",
'PA',"Pennsylvania",
'PR',"Puerto Rico",
'PW',"Palau",
'RI',"Rhode Island",
'SC',"South Carolina",
'SD',"South Dakota",
'TN',"Tennessee",
'TX',"Texas",
'UT',"Utah",
'VA',"Virginia",
'VI',"Virgin Islands",
'VT',"Vermont",
'WA',"Washington",
'WV',"West Virginia",
'WI',"Wisconsin",
'WY',"Wyoming"
);
my %region=(
'ca'=>\%regca,
'us'=>\%regus
);
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_geoip_region_maxmind {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
$MAXNBOFSECTIONGIR=10;
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin $PluginName: InitParams=$InitParams",1);
my ($mode,$tmpdatafile)=split(/\s+/,$InitParams,2);
my ($datafile,$override)=split(/\+/,$tmpdatafile,2);
if (! $datafile) { $datafile="GeoIPRegion.dat"; }
else { $datafile =~ s/%20/ /g; }
if ($type eq 'geoippureperl') {
# With pureperl we always use GEOIP_STANDARD.
# GEOIP_MEMORY_CACHE seems to fail with ActiveState
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
else { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
} else {
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::GEOIP_MEMORY_CACHE(); }
else { $mode=Geo::IP::GEOIP_STANDARD(); }
}
if ($override){ $override =~ s/%20/ /g; $OverrideFile=$override; }
%TmpDomainLookup=();
debug(" Plugin $PluginName: GeoIP initialized type=$type mode=$mode",1);
if ($type eq 'geoippureperl') {
$geoip_region_maxmind = Geo::IP::PurePerl->open($datafile, $mode);
} else {
$geoip_region_maxmind = Geo::IP->open($datafile, $mode);
}
$LoadedOverride=0;
# Fails with some geoip versions
# debug(" Plugin geoip_region_maxmind: GeoIP initialized database_info=".$geoip_region_maxmind->database_info());
if ($geoip_region_maxmind) { debug(" Plugin $PluginName: GeoIP plugin and gi object initialized",1); }
else { return "Error: Failed to create gi object for datafile=".$datafile; }
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLMenuLink_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLMenuLink_geoip_region_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
if ($Debug) { debug(" Plugin $PluginName: AddHTMLMenuLink"); }
if ($categ eq 'who') {
$menu->{"plugin_$PluginName"}=2.1; # Pos
$menulink->{"plugin_$PluginName"}=2; # Type of link
$menutext->{"plugin_$PluginName"}="Regions"; # Text
}
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLGraph_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLGraph_geoip_region_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
my $ShowRegions='H';
$MinHit{'Regions'}=1;
my $total_p; my $total_h; my $total_k;
my $rest_p; my $rest_h; my $rest_k;
if ($Debug) { debug(" Plugin $PluginName: AddHTMLGraph"); }
my $title='Regions';
&tab_head("$title",19,0,'regions');
print "US and CA Regions : ".((scalar keys %_region_h)-($_region_h{'unknown'}?1:0))." | ";
if ($ShowRegions =~ /P/i) { print "$Message[56] | "; }
if ($ShowRegions =~ /P/i) { print "$Message[15] | "; }
if ($ShowRegions =~ /H/i) { print "$Message[57] | "; }
if ($ShowRegions =~ /H/i) { print "$Message[15] | "; }
if ($ShowRegions =~ /B/i) { print "$Message[75] | "; }
if ($ShowRegions =~ /L/i) { print "$Message[9] | "; }
print "
\n";
$total_p=$total_h=$total_k=0;
my $count=0;
&BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Regions'},\%_region_h,\%_region_h);
# Group by country
my @countrylist=('ca','us');
foreach my $country (@countrylist) {
print "".$countryregionlib{$country}." | ";
if ($ShowRegions =~ /P/i) { print " | "; }
if ($ShowRegions =~ /P/i) { print " | "; }
if ($ShowRegions =~ /H/i) { print " | "; }
if ($ShowRegions =~ /H/i) { print " | "; }
if ($ShowRegions =~ /B/i) { print " | "; }
if ($ShowRegions =~ /L/i) { print " | "; }
print "
\n";
foreach my $key (@keylist) {
if ($key eq 'unknown') { next; }
my ($countrycode,$regioncode)=split('_',$key);
if ($countrycode ne $country) { next; }
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int($_region_p{$key}/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($_region_h{$key}/$TotalHits*1000)/10; }
print "".$region{$countrycode}{uc($regioncode)}." ($regioncode) | ";
if ($ShowRegions =~ /P/i) { print "".($_region_p{$key}?Format_Number($_region_p{$key}):" ")." | "; }
if ($ShowRegions =~ /P/i) { print "".($_region_p{$key}?"$p_p %":' ')." | "; }
if ($ShowRegions =~ /H/i) { print "".($_region_h{$key}?Format_Number($_region_h{$key}):" ")." | "; }
if ($ShowRegions =~ /H/i) { print "".($_region_h{$key}?"$p_h %":' ')." | "; }
if ($ShowRegions =~ /B/i) { print "".Format_Bytes($_region_k{$key})." | "; }
if ($ShowRegions =~ /L/i) { print "".($_region_p{$key}?Format_Date($_region_l{$key},1):'-')." | "; }
print "
\n";
$total_p += $_region_p{$key}||0;
$total_h += $_region_h{$key};
$total_k += $_region_k{$key}||0;
$count++;
}
}
if ($Debug) { debug("Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h",2); }
$rest_p=0;
$rest_h=$TotalHits-$total_h;
$rest_k=0;
if ($rest_p > 0 || $rest_h > 0 || $rest_k > 0) { # All other regions
print " | ";
if ($ShowRegions =~ /P/i) { print " | "; }
if ($ShowRegions =~ /P/i) { print " | "; }
if ($ShowRegions =~ /H/i) { print " | "; }
if ($ShowRegions =~ /H/i) { print " | "; }
if ($ShowRegions =~ /B/i) { print " | "; }
if ($ShowRegions =~ /L/i) { print " | "; }
print "
\n";
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int($rest_p/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($rest_h/$TotalHits*1000)/10; }
print "$Message[2]/$Message[0] | ";
if ($ShowRegions =~ /P/i) { print "".($rest_p?Format_Number($rest_p):" ")." | "; }
if ($ShowRegions =~ /P/i) { print "".($rest_p?"$p_p %":' ')." | "; }
if ($ShowRegions =~ /H/i) { print "".($rest_h?Format_Number($rest_h):" ")." | "; }
if ($ShowRegions =~ /H/i) { print "".($rest_h?"$p_h %":' ')." | "; }
if ($ShowRegions =~ /B/i) { print "".Format_Bytes($rest_k)." | "; }
if ($ShowRegions =~ /L/i) { print " | "; }
print "
\n";
}
&tab_end();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetCountryCodeByAddr_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# GetCountryCodeByAddr is called to translate an ip into a country code in lower case.
#-----------------------------------------------------------------------------
# Rem: Not used
sub GetCountryCodeByAddr_geoip_region_maxmind {
my $param="$_[0]";
# <-----
if (!$LoadedOverride){&LoadOverrideFile_geoip_region_maxmind();}
my $res=$TmpDomainLookup{$param}||'';
if (! $res) {
my ($res1,$res2,$countryregion)=();
($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
$res=lc($res1) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: Already resolved to [$res]",5); }
# ----->
return $res;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: GetCountryCodeByName_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# GetCountryCodeByName is called to translate a host name into a country code in lower case.
#-----------------------------------------------------------------------------
# Rem: Not used
sub GetCountryCodeByName_geoip_region_maxmind {
my $param="$_[0]";
# <-----
if (!$LoadedOverride){&LoadOverrideFile_geoip_region_maxmind();}
my $res=$TmpDomainLookup{$param}||'';
if (! $res) {
my ($res1,$res2,$countryregion)=();
($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
$res=lc($res1) || 'unknown';
$TmpDomainLookup{$param}=$res;
if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: [$res]",5); }
}
elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: Already resolved to [$res]",5); }
# ----->
return $res;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: ShowInfoHost_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to add additionnal columns to the Hosts report.
# This function is called when building rows of the report (One call for each
# row). So it allows you to add a column in report, for example with code :
# print "This is a new cell for $param | ";
# Parameters: Host name or ip
#-----------------------------------------------------------------------------
sub ShowInfoHost_geoip_region_maxmind {
my $param="$_[0]";
# <-----
if ($param eq '__title__') {
my $NewLinkParams=${QueryString};
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)output(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
my $NewLinkTarget='';
if ($DetailedReportsOnNewWindows) { $NewLinkTarget=" target=\"awstatsbis\""; }
if (($FrameName eq 'mainleft' || $FrameName eq 'mainright') && $DetailedReportsOnNewWindows < 2) {
$NewLinkParams.="&framename=mainright";
$NewLinkTarget=" target=\"mainright\"";
}
$NewLinkParams =~ s/(&|&)+/&/i;
$NewLinkParams =~ s/^&//; $NewLinkParams =~ s/&$//;
if ($NewLinkParams) { $NewLinkParams="${NewLinkParams}&"; }
print "";
print "GeoIP Region";
print " | ";
}
elsif ($param) {
# try loading our override file if we haven't yet
if (!$LoadedOverride){&LoadOverrideFile_geoip_region_maxmind();}
my $ip=0;
my $key;
if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
$ip=4;
$key=$param;
}
elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address
$ip=6;
$key=$param;
}
print "";
if ($key && $ip==4) {
my ($res1,$res2,$countryregion)=();
my @res = TmpLookup_geoip_region_maxmind($param);
if (@res){
$res1 = $res[0];
$res2 = $res[1];
}else{
($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetRegionByIp for $param: [${res1}_${res2}]",5); }
if (! $PluginsLoaded{'init'}{'geoip'}) {
# Show country
if ($res1 =~ /\w\w/) { print $DomainsHashIDLib{lc($res1)}||uc($res1); }
else { print "$Message[0]"; }
# Show region
if ($res1 =~ /\w\w/ && $res2 =~ /\w\w/) {
print " (";
print $region{lc($res1)}{uc($res2)};
print ")";
}
}
else {
# Show region
if ($res1 =~ /\w\w/ && $res2 =~ /\w\w/) {
print $region{lc($res1)}{uc($res2)};
}
else { print "$Message[0]"; }
}
}
if ($key && $ip==6) {
print "$Message[0]";
}
if (! $key) {
my ($res1,$res2,$countryregion)=();
my @res = TmpLookup_geoip_region_maxmind($param);
if (@res){
$res1 = $res[0];
$res2 = $res[1];
}else{
($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetRegionByName for $param: [${res1}_${res2}]",5); }
if (! $PluginsLoaded{'init'}{'geoip'}) {
# Show country
if ($res1 =~ /\w\w/) { print $DomainsHashIDLib{lc($res1)}||uc($res1); }
else { print "$Message[0]"; }
# Show region
if ($res1 =~ /\w\w/ && $res2 =~ /\w\w/) {
print " (";
print $region{lc($res1)}{uc($res2)};
print ")";
}
}
else {
# Show region
if ($res1 =~ /\w\w/ && $res2 =~ /\w\w/) {
print $region{lc($res1)}{uc($res2)};
}
else { print "$Message[0]"; }
}
}
print " | ";
}
else {
print " | ";
}
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionInitHashArray_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionInitHashArray_geoip_region_maxmind {
# my $param="$_[0]";
# <-----
if ($Debug) { debug(" Plugin $PluginName: Init_HashArray"); }
%_region_p = %_region_h = %_region_k = %_region_l =();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessHostname_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessIp_geoip_region_maxmind {
my $param="$_[0]"; # Param must be an IP
# <-----
my ($res1,$res2,$countryregion)=();
my @res = TmpLookup_geoip_region_maxmind($param);
if (@res){
$res1 = $res[0];
$res2 = $res[1];
}else{
($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetRegionByIp for $param: [${res1}_${res2}]",5); }
if ($res2 =~ /\w\w/) { $countryregion=lc("${res1}_${res2}"); }
else { $countryregion='unknown'; }
# if ($PageBool) { $_region_p{$countryregion}++; }
$_region_h{$countryregion}++;
# if ($timerecord > $_region_l{$countryregion}) { $_region_l{$countryregion}=$timerecord; }
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessHostname_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessHostname_geoip_region_maxmind {
my $param="$_[0]"; # Param must be a hostname
# <-----
my ($res1,$res2,$countryregion)=();
my @res = TmpLookup_geoip_region_maxmind($param);
if (@res){
$res1 = $res[0];
$res2 = $res[1];
}else{
($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetRegionByName for $param: [${res1}_${res2}]",5); }
if ($res2 =~ /\w\w/) { $countryregion=lc("${res1}_${res2}"); }
else { $countryregion='unknown'; }
# if ($PageBool) { $_region_p{$countryregion}++; }
$_region_h{$countryregion}++;
# if ($timerecord > $_region_l{$countryregion}) { $_region_l{$countryregion}=$timerecord; }
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionReadHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionReadHistory_geoip_region_maxmind {
my $issectiontoload=shift;
my $xmlold=shift;
my $xmleb=shift;
my $countlines=shift;
# <-----
if ($Debug) { debug(" Plugin $PluginName: Begin of PLUGIN_$PluginName"); }
my @field=();
my $count=0;my $countloaded=0;
do {
if ($field[0]) {
$count++;
if ($issectiontoload) {
$countloaded++;
if ($field[2]) { $_region_h{$field[0]}+=$field[2]; }
}
}
$_=;
chomp $_; s/\r//;
@field=split(/\s+/,($xmlold?XMLDecodeFromHisto($_):$_));
$countlines++;
}
until ($field[0] eq "END_PLUGIN_$PluginName" || $field[0] eq "${xmleb}END_PLUGIN_$PluginName" || ! $_);
if ($field[0] ne "END_PLUGIN_$PluginName" && $field[0] ne "${xmleb}END_PLUGIN_$PluginName") { error("History file is corrupted (End of section PLUGIN not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).","","",1); }
if ($Debug) { debug(" Plugin $PluginName: End of PLUGIN_$PluginName section ($count entries, $countloaded loaded)"); }
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionWriteHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionWriteHistory_geoip_region_maxmind {
my ($xml,$xmlbb,$xmlbs,$xmlbe,$xmlrb,$xmlrs,$xmlre,$xmleb,$xmlee)=(shift,shift,shift,shift,shift,shift,shift,shift,shift);
if ($Debug) { debug(" Plugin $PluginName: SectionWriteHistory_$PluginName start - ".(scalar keys %_region_h)); }
# <-----
print HISTORYTMP "\n";
if ($xml) { print HISTORYTMP "$MAXNBOFSECTIONGIR\n"; }
print HISTORYTMP "# Plugin key - Pages - Hits - Bandwidth - Last access\n";
#print HISTORYTMP "# The $MaxNbOfExtra[$extranum] first number of hits are first\n";
$ValueInFile{"plugin_$PluginName"}=tell HISTORYTMP;
print HISTORYTMP "${xmlbb}BEGIN_PLUGIN_$PluginName${xmlbs}".(scalar keys %_region_h)."${xmlbe}\n";
&BuildKeyList($MAXNBOFSECTIONGIR,1,\%_region_h,\%_region_h);
my %keysinkeylist=();
foreach (@keylist) {
$keysinkeylist{$_}=1;
#my $page=$_region_p{$_}||0;
#my $bytes=$_region_k{$_}||0;
#my $lastaccess=$_region_l{$_}||'';
print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_region_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
foreach (keys %_region_h) {
if ($keysinkeylist{$_}) { next; }
#my $page=$_region_p{$_}||0;
#my $bytes=$_region_k{$_}||0;
#my $lastaccess=$_region_l{$_}||'';
print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_region_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
print HISTORYTMP "${xmleb}END_PLUGIN_$PluginName${xmlee}\n";
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: LoadOverrideFile
# Attempts to load a comma delimited file that will override the GeoIP database
# Useful for Intranet records
# CSV format: IP,2-char Country code, region
#-----------------------------------------------------------------------------
sub LoadOverrideFile_geoip_region_maxmind{
my $filetoload="";
if ($OverrideFile){
if (!open(GEOIPFILE, $OverrideFile)){
debug("Plugin $PluginName: Unable to open override file: $OverrideFile");
$LoadedOverride = 1;
return;
}
}else{
my $conf = (exists(&Get_Config_Name) ? Get_Config_Name() : $SiteConfig);
if ($conf && open(GEOIPFILE,"$DirData/$PluginName.$conf.txt")) { $filetoload="$DirData/$PluginName.$conf.txt"; }
elsif (open(GEOIPFILE,"$DirData/$PluginName.txt")) { $filetoload="$DirData/$PluginName.txt"; }
else { debug("No override file \"$DirData/$PluginName.txt\": $!"); }
}
if ($filetoload)
{
# This is the fastest way to load with regexp that I know
while (){
chomp $_;
s/\r//;
my @record = split(",", $_);
# replace quotes if they were used in the file
foreach (@record){ $_ =~ s/"//g; }
# now we need to copy our file values in the order to mimic the lookup values
my @res = ();
$res[0] = $record[1]; # country code
$res[1] = $record[2]; # region code
# store in hash
$TmpDomainLookup{$record[0]} = [@res];
}
close GEOIPFILE;
debug(" Plugin $PluginName: Overload file loaded: ".(scalar keys %TmpDomainLookup)." entries found.");
}
$LoadedOverride = 1;
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: TmpLookup
# Searches the temporary hash for the parameter value and returns the corresponding
# GEOIP entry
#-----------------------------------------------------------------------------
sub TmpLookup_geoip_region_maxmind(){
$param = shift;
if (!$LoadedOverride){&LoadOverrideFile_geoip_region_maxmind();}
#my @val = ();
#if ($geoip_region_maxmind &&
#(($type eq 'geoip' && $geoip_region_maxmind->VERSION >= 1.30) ||
# $type eq 'geoippureperl' && $geoip_region_maxmind->VERSION >= 1.17)){
# @val = @{$TmpDomainLookup{$geoip_region_maxmind->get_ip_address($param)}};
#}
#else {@val = @{$TmpDomainLookup{$param};}}
#return @val;
if ($TmpDomainLookup{$param}) { return @{$TmpDomainLookup{$param};} }
else { return; }
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/geoip_isp_maxmind.pm 0000640 0001750 0001750 00000046544 12410217071 021444 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# GeoIp_Isp_Maxmind AWStats plugin
# This plugin allow you to add a city report.
# Need the licensed ISP database from Maxmind.
#-----------------------------------------------------------------------------
# Perl Required Modules: Geo::IP or Geo::IP::PurePerl
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
use vars qw/ $type /;
$type='geoip';
if (!eval ('require "Geo/IP.pm";')) {
$error1=$@;
$type='geoippureperl';
if (!eval ('require "Geo/IP/PurePerl.pm";')) {
$error2=$@;
$ret=($error1||$error2)?"Error:\n$error1$error2":"";
$ret.="Error: Need Perl module Geo::IP or Geo::IP::PurePerl";
return $ret;
}
}
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="6.2";
my $PluginHooksFunctions="AddHTMLMenuLink AddHTMLGraph ShowInfoHost SectionInitHashArray SectionProcessIp SectionProcessHostname SectionReadHistory SectionWriteHistory";
my $PluginName="geoip_isp_maxmind";
my $LoadedOverride=0;
my $OverrideFile="";
my %TmpDomainLookup;
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$geoip_isp_maxmind
%_isp_p
%_isp_h
%_isp_k
%_isp_l
$MAXNBOFSECTIONGIR
$MAXLENGTH
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_geoip_isp_maxmind {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
$MAXNBOFSECTIONGIR=10;
$MAXLENGTH=20;
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
debug(" Plugin $PluginName: InitParams=$InitParams",1);
my ($mode,$tmpdatafile)=split(/\s+/,$InitParams,2);
my ($datafile,$override)=split(/\+/,$tmpdatafile,2);
if (! $datafile) { $datafile="GeoIPIsp.dat"; }
else { $datafile =~ s/%20/ /g; }
if ($type eq 'geoippureperl') {
# With pureperl with always use GEOIP_STANDARD.
# GEOIP_MEMORY_CACHE seems to fail with ActiveState
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
else { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }
} else {
if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::GEOIP_MEMORY_CACHE(); }
else { $mode=Geo::IP::GEOIP_STANDARD(); }
}
if ($override){ $override =~ s/%20/ /g; $OverrideFile=$override; }
%TmpDomainLookup=();
debug(" Plugin $PluginName: GeoIP initialized type=$type mode=$mode",1);
if ($type eq 'geoippureperl') {
$geoip_isp_maxmind = Geo::IP::PurePerl->open($datafile, $mode);
} else {
$geoip_isp_maxmind = Geo::IP->open($datafile, $mode);
}
$LoadedOverride=0;
# Fails on some GeoIP version
# debug(" Plugin geoip_isp_maxmind: GeoIP initialized database_info=".$geoip_isp_maxmind->database_info());
if ($geoip_isp_maxmind) { debug(" Plugin $PluginName: GeoIP plugin and gi object initialized",1); }
else { return "Error: Failed to create gi object for datafile=".$datafile; }
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLMenuLink_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLMenuLink_geoip_isp_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
if ($Debug) { debug(" Plugin $PluginName: AddHTMLMenuLink"); }
if ($categ eq 'who') {
$menu->{"plugin_$PluginName"}=0.6; # Pos
$menulink->{"plugin_$PluginName"}=2; # Type of link
$menutext->{"plugin_$PluginName"}="ISP"; # Text
}
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: AddHTMLGraph_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub AddHTMLGraph_geoip_isp_maxmind {
my $categ=$_[0];
my $menu=$_[1];
my $menulink=$_[2];
my $menutext=$_[3];
# <-----
my $ShowISP='H';
$MinHit{'Isp'}=1;
my $total_p; my $total_h; my $total_k;
my $rest_p; my $rest_h; my $rest_k;
if ($Debug) { debug(" Plugin $PluginName: AddHTMLGraph $categ $menu $menulink $menutext"); }
my $title='ISP';
&tab_head("$title",19,0,'isp');
print "ISP : ".((scalar keys %_isp_h)-($_isp_h{'unknown'}?1:0))." | ";
if ($ShowISP =~ /P/i) { print "$Message[56] | "; }
if ($ShowISP =~ /P/i) { print "$Message[15] | "; }
if ($ShowISP =~ /H/i) { print "$Message[57] | "; }
if ($ShowISP =~ /H/i) { print "$Message[15] | "; }
if ($ShowISP =~ /B/i) { print "$Message[75] | "; }
if ($ShowISP =~ /L/i) { print "$Message[9] | "; }
print "
\n";
$total_p=$total_h=$total_k=0;
my $count=0;
&BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Isp'},\%_isp_h,\%_isp_h);
foreach my $key (@keylist) {
if ($key eq 'unknown') { next; }
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int($_isp_p{$key}/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($_isp_h{$key}/$TotalHits*1000)/10; }
print "";
my $isp=$key; $isp =~ s/_/ /g;
print "".ucfirst($isp)." | ";
if ($ShowISP =~ /P/i) { print "".($_isp_p{$key}?Format_Number($_isp_p{$key}):" ")." | "; }
if ($ShowISP =~ /P/i) { print "".($_isp_p{$key}?"$p_p %":' ')." | "; }
if ($ShowISP =~ /H/i) { print "".($_isp_h{$key}?Format_Number($_isp_h{$key}):" ")." | "; }
if ($ShowISP =~ /H/i) { print "".($_isp_h{$key}?"$p_h %":' ')." | "; }
if ($ShowISP =~ /B/i) { print "".Format_Bytes($_isp_k{$key})." | "; }
if ($ShowISP =~ /L/i) { print "".($_isp_p{$key}?Format_Date($_isp_l{$key},1):'-')." | "; }
print "
\n";
$total_p += $_isp_p{$key}||0;
$total_h += $_isp_h{$key};
$total_k += $_isp_k{$key}||0;
$count++;
}
if ($Debug) { debug("Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h",2); }
$rest_p=0;
$rest_h=$TotalHits-$total_h;
$rest_k=0;
if ($rest_p > 0 || $rest_h > 0 || $rest_k > 0) { # All other cities
# print "";
# print " | ";
# if ($ShowISP =~ /P/i) { print " | "; }
# if ($ShowISP =~ /P/i) { print " | "; }
# if ($ShowISP =~ /H/i) { print " | "; }
# if ($ShowISP =~ /H/i) { print " | "; }
# if ($ShowISP =~ /B/i) { print " | "; }
# if ($ShowISP =~ /L/i) { print " | "; }
# print "
\n";
my $p_p; my $p_h;
if ($TotalPages) { $p_p=int($rest_p/$TotalPages*1000)/10; }
if ($TotalHits) { $p_h=int($rest_h/$TotalHits*1000)/10; }
print "";
print "$Message[2]/$Message[0] | ";
if ($ShowISP =~ /P/i) { print "".($rest_p?Format_Number($rest_p):" ")." | "; }
if ($ShowISP =~ /P/i) { print "".($rest_p?"$p_p %":' ')." | "; }
if ($ShowISP =~ /H/i) { print "".($rest_h?Format_Number($rest_h):" ")." | "; }
if ($ShowISP =~ /H/i) { print "".($rest_h?"$p_h %":' ')." | "; }
if ($ShowISP =~ /B/i) { print "".Format_Bytes($rest_k)." | "; }
if ($ShowISP =~ /L/i) { print " | "; }
print "
\n";
}
&tab_end();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: ShowInfoHost_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
# Function called to add additionnal columns to the Hosts report.
# This function is called when building rows of the report (One call for each
# row). So it allows you to add a column in report, for example with code :
# print "This is a new cell for $param | ";
# Parameters: Host name or ip
#-----------------------------------------------------------------------------
sub ShowInfoHost_geoip_isp_maxmind {
my $param="$_[0]";
# <-----
if ($param eq '__title__') {
my $NewLinkParams=${QueryString};
$NewLinkParams =~ s/(^|&|&)update(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)output(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)staticlinks(=\w*|$)//i;
$NewLinkParams =~ s/(^|&|&)framename=[^&]*//i;
my $NewLinkTarget='';
if ($DetailedReportsOnNewWindows) { $NewLinkTarget=" target=\"awstatsbis\""; }
if (($FrameName eq 'mainleft' || $FrameName eq 'mainright') && $DetailedReportsOnNewWindows < 2) {
$NewLinkParams.="&framename=mainright";
$NewLinkTarget=" target=\"mainright\"";
}
$NewLinkParams =~ s/(&|&)+/&/i;
$NewLinkParams =~ s/^&//; $NewLinkParams =~ s/&$//;
if ($NewLinkParams) { $NewLinkParams="${NewLinkParams}&"; }
print "";
print "GeoIP ISP";
print " | ";
}
elsif ($param) {
my $ip=0;
my $key;
if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
$ip=4;
$key=$param;
}
elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address
$ip=6;
$key=$param;
}
print "";
if ($key && $ip==4) {
my $isp = TmpLookup_geoip_isp_maxmind($param);
if (!$isp && $type eq 'geoippureperl')
{
# Function isp_by_addr does not exists in PurePerl but isp_by_name do same
$isp=$geoip_isp_maxmind->isp_by_name($param) if $geoip_isp_maxmind;
}
elsif (!$isp)
{
# Function isp_by_addr does not exits, so we use org_by_addr
$isp=$geoip_isp_maxmind->org_by_addr($param) if $geoip_isp_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetIspByIp for $param: [$isp]",5); }
if ($isp) {
if (length($isp) <= $MAXLENGTH) {
print "$isp";
}
else {
print substr($isp,0,$MAXLENGTH).'...';
}
}
else { print "$Message[0]"; }
}
if ($key && $ip==6) {
print "$Message[0]";
}
if (! $key) {
my $isp = TmpLookup_geoip_isp_maxmind($param);
if (!$isp && $type eq 'geoippureperl')
{
$isp=$geoip_isp_maxmind->isp_by_name($param) if $geoip_isp_maxmind;
}
elsif (!$isp)
{
$isp=$geoip_isp_maxmind->isp_by_name($param) if $geoip_isp_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetIspByHostname for $param: [$isp]",5); }
if ($isp) {
if (length($isp) <= $MAXLENGTH) {
print "$isp";
}
else {
print substr($isp,0,$MAXLENGTH).'...';
}
}
else { print "$Message[0]"; }
}
print " | ";
}
else {
print " | ";
}
return 1;
# ----->
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionInitHashArray_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionInitHashArray_geoip_isp_maxmind {
# my $param="$_[0]";
# <-----
if ($Debug) { debug(" Plugin $PluginName: Init_HashArray"); }
%_isp_p = %_isp_h = %_isp_k = %_isp_l =();
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessIP_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessIp_geoip_isp_maxmind {
my $param="$_[0]"; # Param must be an IP
# <-----
my $isp = TmpLookup_geoip_isp_maxmind($param);
if (!$isp && $type eq 'geoippureperl')
{
# Function isp_by_addr does not exists in PurePerl but isp_by_name do same
$isp=$geoip_isp_maxmind->isp_by_name($param) if $geoip_isp_maxmind;
}
elsif(!$isp)
{
# Function isp_by_addr does not exits, so we use org_by_addr
$isp=$geoip_isp_maxmind->org_by_addr($param) if $geoip_isp_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetIspByIp for $param: [$isp]",5); }
if ($isp) {
$isp =~ s/\s/_/g;
$_isp_h{$isp}++;
} else {
$_isp_h{'unknown'}++;
}
# if ($timerecord > $_isp_l{$city}) { $_isp_l{$city}=$timerecord; }
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionProcessHostname_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionProcessHostname_geoip_isp_maxmind {
my $param="$_[0]"; # Param must be an IP
# <-----
my $isp = TmpLookup_geoip_isp_maxmind($param);
if (!$isp && $type eq 'geoippureperl')
{
$isp=$geoip_isp_maxmind->isp_by_name($param) if $geoip_isp_maxmind;
}
elsif(!$isp)
{
$isp=$geoip_isp_maxmind->isp_by_name($param) if $geoip_isp_maxmind;
}
if ($Debug) { debug(" Plugin $PluginName: GetIspByHostname for $param: [$isp]",5); }
if ($isp) {
$isp =~ s/\s/_/g;
$_isp_h{$isp}++;
} else {
$_isp_h{'unknown'}++;
}
# if ($timerecord > $_isp_l{$city}) { $_isp_l{$city}=$timerecord; }
# ----->
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionReadHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionReadHistory_geoip_isp_maxmind {
my $issectiontoload=shift;
my $xmlold=shift;
my $xmleb=shift;
my $countlines=shift;
# <-----
if ($Debug) { debug(" Plugin $PluginName: Begin of PLUGIN_$PluginName section"); }
my @field=();
my $count=0;my $countloaded=0;
do {
if ($field[0]) {
$count++;
if ($issectiontoload) {
$countloaded++;
if ($field[2]) { $_isp_h{$field[0]}+=$field[2]; }
}
}
$_=;
chomp $_; s/\r//;
@field=split(/\s+/,($xmlold?XMLDecodeFromHisto($_):$_));
$countlines++;
}
until ($field[0] eq "END_PLUGIN_$PluginName" || $field[0] eq "${xmleb}END_PLUGIN_$PluginName" || ! $_);
if ($field[0] ne "END_PLUGIN_$PluginName" && $field[0] ne "${xmleb}END_PLUGIN_$PluginName") { error("History file is corrupted (End of section PLUGIN not found).\nRestore a recent backup of this file (data for this month will be restored to backup date), remove it (data for month will be lost), or remove the corrupted section in file (data for at least this section will be lost).","","",1); }
if ($Debug) { debug(" Plugin $PluginName: End of PLUGIN_$PluginName ($count entries, $countloaded loaded)"); }
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: SectionWriteHistory_pluginname
# UNIQUE: NO (Several plugins using this function can be loaded)
#-----------------------------------------------------------------------------
sub SectionWriteHistory_geoip_isp_maxmind {
my ($xml,$xmlbb,$xmlbs,$xmlbe,$xmlrb,$xmlrs,$xmlre,$xmleb,$xmlee)=(shift,shift,shift,shift,shift,shift,shift,shift,shift);
if ($Debug) { debug(" Plugin $PluginName: SectionWriteHistory_$PluginName start - ".(scalar keys %_isp_h)); }
# <-----
print HISTORYTMP "\n";
if ($xml) { print HISTORYTMP "$MAXNBOFSECTIONGIR\n"; }
print HISTORYTMP "# Plugin key - Pages - Hits - Bandwidth - Last access\n";
#print HISTORYTMP "# The $MaxNbOfExtra[$extranum] first number of hits are first\n";
$ValueInFile{"plugin_$PluginName"}=tell HISTORYTMP;
print HISTORYTMP "${xmlbb}BEGIN_PLUGIN_$PluginName${xmlbs}".(scalar keys %_isp_h)."${xmlbe}\n";
&BuildKeyList($MAXNBOFSECTIONGIR,1,\%_isp_h,\%_isp_h);
my %keysinkeylist=();
foreach (@keylist) {
$keysinkeylist{$_}=1;
#my $page=$_isp_p{$_}||0;
#my $bytes=$_isp_k{$_}||0;
#my $lastaccess=$_isp_l{$_}||'';
print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_isp_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
foreach (keys %_isp_h) {
if ($keysinkeylist{$_}) { next; }
#my $page=$_isp_p{$_}||0;
#my $bytes=$_isp_k{$_}||0;
#my $lastaccess=$_isp_l{$_}||'';
print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_isp_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
}
print HISTORYTMP "${xmleb}END_PLUGIN_$PluginName${xmlee}\n";
# ----->
return 0;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: LoadOverrideFile
# Attempts to load a comma delimited file that will override the GeoIP database
# Useful for Intranet records
# CSV format: IP,"isp"
#-----------------------------------------------------------------------------
sub LoadOverrideFile_geoip_isp_maxmind{
my $filetoload="";
if ($OverrideFile){
if (!open(GEOIPFILE, $OverrideFile)){
debug("Plugin $PluginName: Unable to open override file: $OverrideFile");
$LoadedOverride = 1;
return;
}
}else{
my $conf = (exists(&Get_Config_Name) ? Get_Config_Name() : $SiteConfig);
if ($conf && open(GEOIPFILE,"$DirData/$PluginName.$conf.txt")) { $filetoload="$DirData/$PluginName.$conf.txt"; }
elsif (open(GEOIPFILE,"$DirData/$PluginName.txt")) { $filetoload="$DirData/$PluginName.txt"; }
else { debug("No override file \"$DirData/$PluginName.txt\": $!"); }
}
if ($filetoload)
{
# This is the fastest way to load with regexp that I know
while (){
chomp $_;
s/\r//;
my @record = split(",", $_);
# replace quotes if they were used in the file
foreach (@record){ $_ =~ s/"//g; }
# store in hash
$TmpDomainLookup{$record[0]} = $record[1];
}
close GEOIPFILE;
debug(" Plugin $PluginName: Overload file loaded: ".(scalar keys %TmpDomainLookup)." entries found.");
}
$LoadedOverride = 1;
return;
}
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: TmpLookup
# Searches the temporary hash for the parameter value and returns the corresponding
# GEOIP entry
#-----------------------------------------------------------------------------
sub TmpLookup_geoip_isp_maxmind(){
$param = shift;
if (!$LoadedOverride){&LoadOverrideFile_geoip_isp_maxmind();}
#my $val;
#if ($geoip_isp_maxmind &&
#(($type eq 'geoip' && $geoip_isp_maxmind->VERSION >= 1.30) ||
# $type eq 'geoippureperl' && $geoip_isp_maxmind->VERSION >= 1.17)){
# $val = $TmpDomainLookup{$geoip_isp_maxmind->get_ip_address($param)};
#}
#else {$val = $TmpDomainLookup{$param};}
#return $val || '';
return $TmpDomainLookup{$param}||'';
}
1; # Do not remove this line
awstats-7.4/wwwroot/cgi-bin/plugins/graphapplet.pm 0000640 0001750 0001750 00000011644 12410217071 020251 0 ustar sk sk #!/usr/bin/perl
#-----------------------------------------------------------------------------
# GraphApplet AWStats plugin
# Allow AWStats to replace bar graphs with an Applet (awgraphapplet) that draw
# 3D graphs instead.
#-----------------------------------------------------------------------------
# Perl Required Modules: None
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
# ----->
#use strict;
no strict "refs";
#-----------------------------------------------------------------------------
# PLUGIN VARIABLES
#-----------------------------------------------------------------------------
# <-----
# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
my $PluginNeedAWStatsVersion="6.0";
my $PluginHooksFunctions="ShowGraph";
# ----->
# <-----
# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
use vars qw/
$DirClasses
/;
# ----->
#-----------------------------------------------------------------------------
# PLUGIN FUNCTION: Init_pluginname
#-----------------------------------------------------------------------------
sub Init_graphapplet {
my $InitParams=shift;
my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
# <-----
# ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
$DirClasses=$InitParams;
# ----->
return ($checkversion?$checkversion:"$PluginHooksFunctions");
}
#-------------------------------------------------------
# PLUGIN FUNCTION: ShowGraph_pluginname
# UNIQUE: YES (Only one plugin using this function can be loaded)
# Add the code for call to applet awgraphapplet
# Parameters: $title $type $showmonthstats \@blocklabel,\@vallabel,\@valcolor,\@valmax,\@valtotal
# Input: None
# Output: HTML code for awgraphapplet insertion
# Return: 0 OK, 1 Error
#-------------------------------------------------------
sub ShowGraph_graphapplet() {
my $title=shift;
my $type=shift;
my $showmonthstats=shift;
my $blocklabel=shift;
my $vallabel=shift;
my $valcolor=shift;
my $valmax=shift;
my $valtotal=shift;
my $valaverage=shift;
my $valdata=shift;
my $graphwidth=780;
my $graphheight=400;
my $blockspacing=5;
my $valspacing=1;
my $valwidth=5;
my $barsize=0;
my $blockfontsize=11;
if ($type eq 'month') { $graphwidth=540; $graphheight=160; $blockspacing=8; $valspacing=0; $valwidth=6; $barsize=$BarHeight; $blockfontsize=11; }
elsif ($type eq 'daysofmonth') { $graphwidth=640; $graphheight=160; $blockspacing=3; $valspacing=0; $valwidth=4; $barsize=$BarHeight; $blockfontsize=9; }
elsif ($type eq 'daysofweek') { $graphwidth=300; $graphheight=160; $blockspacing=10; $valspacing=0; $valwidth=6; $barsize=$BarHeight; $blockfontsize=10; }
elsif ($type eq 'hours') { $graphwidth=600; $graphheight=160; $blockspacing=4; $valspacing=0; $valwidth=6; $barsize=$BarHeight; $blockfontsize=11; }
else { debug("Unknown type parameter in ShowGraph_graphapplet function: $type", 1); return 0; }
# print "