1 rizwank 1.1 #!/usr/bin/perl
2 #-----------------------------------------------------------------------------
3 # GeoIp_Region_Maxmind AWStats plugin
4 # This plugin allow you to add a region report with regions detected
5 # from a Geographical database (US and Canada).
6 # Need the licensed region database from Maxmind.
7 #-----------------------------------------------------------------------------
8 # Perl Required Modules: Geo::IP (Geo::IP::PurePerl is not yet supported)
9 #-----------------------------------------------------------------------------
10 # $Revision: 1.5 $ - $Author: eldy $ - $Date: 2004/12/10 22:28:39 $
11
12
13 # <-----
14 # ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES
15 if (!eval ('require "Geo/IP.pm";')) {
16 return $@?"Error: $@":"Error: Need Perl module Geo::IP (Geo::IP::PurePerl is not yet supported)";
17 }
18 # ----->
19 use strict;no strict "refs";
20
21
22 rizwank 1.1
23 #-----------------------------------------------------------------------------
24 # PLUGIN VARIABLES
25 #-----------------------------------------------------------------------------
26 # <-----
27 # ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN
28 # AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.
29 my $PluginNeedAWStatsVersion="6.2";
30 my $PluginHooksFunctions="AddHTMLMenuLink AddHTMLGraph ShowInfoHost SectionInitHashArray SectionProcessIp SectionProcessHostname SectionReadHistory SectionWriteHistory";
31 # ----->
32
33 # <-----
34 # IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.
35 use vars qw/
36 $geoip_region_maxmind
37 %_region_p
38 %_region_h
39 %_region_k
40 %_region_l
41 $MAXNBOFSECTIONGIR
42 %region
43 rizwank 1.1 /;
44 my %countrylib=('ca'=>'Canada','us'=>'USA');
45 my %countryregionlib=('ca'=>'Canadian Regions','us'=>'US regions');
46 my %regca=(
47 'AB',"Alberta",
48 'BC',"British Columbia",
49 'MB',"Manitoba",
50 'NB',"New Brunswick",
51 'NF',"Newfoundland",
52 'NS',"Nova Scotia",
53 'NU',"Nunavut",
54 'ON',"Ontario",
55 'PE',"Prince Edward Island",
56 'QC',"Quebec",
57 'SK',"Saskatchewan",
58 'NT',"Northwest Territories",
59 'YT',"Yukon Territory"
60 );
61 my %regus=(
62 'AA',"Armed Forces Americas",
63 'AE',"Armed Forces Europe, Middle East, & Canada",
64 rizwank 1.1 'AK',"Alaska",
65 'AL',"Alabama",
66 'AP',"Armed Forces Pacific",
67 'AR',"Arkansas",
68 'AS',"American Samoa",
69 'AZ',"Arizona",
70 'CA',"California",
71 'CO',"Colorado",
72 'CT',"Connecticut",
73 'DC',"District of Columbia",
74 'DE',"Delaware",
75 'FL',"Florida",
76 'FM',"Federated States of Micronesia",
77 'GA',"Georgia",
78 'GU',"Guam",
79 'HI',"Hawaii",
80 'IA',"Iowa",
81 'ID',"Idaho",
82 'IL',"Illinois",
83 'IN',"Indiana",
84 'KS',"Kansas",
85 rizwank 1.1 'KY',"Kentucky",
86 'LA',"Louisiana",
87 'MA',"Massachusetts",
88 'MD',"Maryland",
89 'ME',"Maine",
90 'MH',"Marshall Islands",
91 'MI',"Michigan",
92 'MN',"Minnesota",
93 'MO',"Missouri",
94 'MP',"Northern Mariana Islands",
95 'MS',"Mississippi",
96 'MT',"Montana",
97 'NC',"North Carolina",
98 'ND',"North Dakota",
99 'NE',"Nebraska",
100 'NH',"New Hampshire",
101 'NJ',"New Jersey",
102 'NM',"New Mexico",
103 'NV',"Nevada",
104 'NY',"New York",
105 'OH',"Ohio",
106 rizwank 1.1 'OK',"Oklahoma",
107 'OR',"Oregon",
108 'PA',"Pennsylvania",
109 'PR',"Puerto Rico",
110 'PW',"Palau",
111 'RI',"Rhode Island",
112 'SC',"South Carolina",
113 'SD',"South Dakota",
114 'TN',"Tennessee",
115 'TX',"Texas",
116 'UT',"Utah",
117 'VA',"Virginia",
118 'VI',"Virgin Islands",
119 'VT',"Vermont",
120 'WA',"Washington",
121 'WV',"West Virginia",
122 'WI',"Wisconsin",
123 'WY',"Wyoming"
124 );
125 my %region=(
126 'ca'=>\%regca,
127 rizwank 1.1 'us'=>\%regus
128 );
129 # ----->
130
131
132 #-----------------------------------------------------------------------------
133 # PLUGIN FUNCTION: Init_pluginname
134 #-----------------------------------------------------------------------------
135 sub Init_geoip_region_maxmind {
136 my $InitParams=shift;
137 my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);
138 $MAXNBOFSECTIONGIR=10;
139
140 # <-----
141 # ENTER HERE CODE TO DO INIT PLUGIN ACTIONS
142 debug(" Plugin geoip_region_maxmind: InitParams=$InitParams",1);
143 # if ($UpdateStats) {
144 my ($mode,$datafile)=split(/\s+/,$InitParams,2);
145 if (! $datafile) { $datafile="GeoIPRegion.dat"; }
146 if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::GEOIP_MEMORY_CACHE(); }
147 else { $mode=Geo::IP::GEOIP_STANDARD(); }
148 rizwank 1.1 debug(" Plugin geoip_region_maxmind: GeoIP initialized in mode $mode",1);
149 $geoip_region_maxmind = Geo::IP->open($datafile, $mode);
150 # }
151 # ----->
152
153 return ($checkversion?$checkversion:"$PluginHooksFunctions");
154 }
155
156
157 #-----------------------------------------------------------------------------
158 # PLUGIN FUNCTION: AddHTMLMenuLink_pluginname
159 # UNIQUE: NO (Several plugins using this function can be loaded)
160 #-----------------------------------------------------------------------------
161 sub AddHTMLMenuLink_geoip_region_maxmind {
162 my $categ=$_[0];
163 my $menu=$_[1];
164 my $menulink=$_[2];
165 my $menutext=$_[3];
166 # <-----
167 if ($Debug) { debug(" Plugin geoip_region_maxmind: AddHTMLMenuLink"); }
168 if ($categ eq 'who') {
169 rizwank 1.1 $menu->{'plugin_geoip_region_maxmind'}=2.1; # Pos
170 $menulink->{'plugin_geoip_region_maxmind'}=2; # Type of link
171 $menutext->{'plugin_geoip_region_maxmind'}="Regions"; # Text
172 }
173 # ----->
174 return 0;
175 }
176
177
178 #-----------------------------------------------------------------------------
179 # PLUGIN FUNCTION: AddHTMLGraph_pluginname
180 # UNIQUE: NO (Several plugins using this function can be loaded)
181 #-----------------------------------------------------------------------------
182 sub AddHTMLGraph_geoip_region_maxmind {
183 my $categ=$_[0];
184 my $menu=$_[1];
185 my $menulink=$_[2];
186 my $menutext=$_[3];
187 # <-----
188 my $ShowRegions='H';
189 $MinHit{'Regions'}=1;
190 rizwank 1.1 my $total_p; my $total_h; my $total_k;
191 my $rest_p; my $rest_h; my $rest_k;
192
193 if ($Debug) { debug(" Plugin geoip_region_maxmind: AddHTMLGraph"); }
194 my $title='Regions';
195 &tab_head("$title",19,0,'regions');
196 print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>US and CA Regions : ".((scalar keys %_region_h)-($_region_h{'unknown'}?1:0))."</th>";
197 if ($ShowRegions =~ /P/i) { print "<th bgcolor=\"#$color_p\" width=\"80\">$Message[56]</th>"; }
198 if ($ShowRegions =~ /P/i) { print "<th bgcolor=\"#$color_p\" width=\"80\">$Message[15]</th>"; }
199 if ($ShowRegions =~ /H/i) { print "<th bgcolor=\"#$color_h\" width=\"80\">$Message[57]</th>"; }
200 if ($ShowRegions =~ /H/i) { print "<th bgcolor=\"#$color_h\" width=\"80\">$Message[15]</th>"; }
201 if ($ShowRegions =~ /B/i) { print "<th bgcolor=\"#$color_k\" width=\"80\">$Message[75]</th>"; }
202 if ($ShowRegions =~ /L/i) { print "<th width=\"120\">$Message[9]</th>"; }
203 print "</tr>\n";
204 $total_p=$total_h=$total_k=0;
205 my $count=0;
206 &BuildKeyList($MaxRowsInHTMLOutput,$MinHit{'Regions'},\%_region_h,\%_region_h);
207 # Group by country
208 my @countrylist=('ca','us');
209 foreach my $country (@countrylist) {
210 print "<tr><td class=\"aws\"><b>".$countryregionlib{$country}."</b></td>";
211 rizwank 1.1 if ($ShowRegions =~ /P/i) { print "<td> </td>"; }
212 if ($ShowRegions =~ /P/i) { print "<td> </td>"; }
213 if ($ShowRegions =~ /H/i) { print "<td> </td>"; }
214 if ($ShowRegions =~ /H/i) { print "<td> </td>"; }
215 if ($ShowRegions =~ /B/i) { print "<td> </td>"; }
216 if ($ShowRegions =~ /L/i) { print "<td> </td>"; }
217 print "</tr>\n";
218 foreach my $key (@keylist) {
219 if ($key eq 'unknown') { next; }
220 my ($countrycode,$regioncode)=split('_',$key);
221 if ($countrycode ne $country) { next; }
222 my $p_p; my $p_h;
223 if ($TotalPages) { $p_p=int($_region_p{$key}/$TotalPages*1000)/10; }
224 if ($TotalHits) { $p_h=int($_region_h{$key}/$TotalHits*1000)/10; }
225 print "<tr><td class=\"aws\">".$region{$countrycode}{uc($regioncode)}." ($regioncode)</td>";
226 if ($ShowRegions =~ /P/i) { print "<td>".($_region_p{$key}?$_region_p{$key}:" ")."</td>"; }
227 if ($ShowRegions =~ /P/i) { print "<td>".($_region_p{$key}?"$p_p %":' ')."</td>"; }
228 if ($ShowRegions =~ /H/i) { print "<td>".($_region_h{$key}?$_region_h{$key}:" ")."</td>"; }
229 if ($ShowRegions =~ /H/i) { print "<td>".($_region_h{$key}?"$p_h %":' ')."</td>"; }
230 if ($ShowRegions =~ /B/i) { print "<td>".Format_Bytes($_region_k{$key})."</td>"; }
231 if ($ShowRegions =~ /L/i) { print "<td>".($_region_p{$key}?Format_Date($_region_l{$key},1):'-')."</td>"; }
232 rizwank 1.1 print "</tr>\n";
233 $total_p += $_region_p{$key}||0;
234 $total_h += $_region_h{$key};
235 $total_k += $_region_k{$key}||0;
236 $count++;
237 }
238 }
239 if ($Debug) { debug("Total real / shown : $TotalPages / $total_p - $TotalHits / $total_h - $TotalBytes / $total_h",2); }
240 $rest_p=0;
241 $rest_h=$TotalHits-$total_h;
242 $rest_k=0;
243 if ($rest_p > 0 || $rest_h > 0 || $rest_k > 0) { # All other regions
244 print "<tr><td class=\"aws\"> </td>";
245 if ($ShowRegions =~ /P/i) { print "<td> </td>"; }
246 if ($ShowRegions =~ /P/i) { print "<td> </td>"; }
247 if ($ShowRegions =~ /H/i) { print "<td> </td>"; }
248 if ($ShowRegions =~ /H/i) { print "<td> </td>"; }
249 if ($ShowRegions =~ /B/i) { print "<td> </td>"; }
250 if ($ShowRegions =~ /L/i) { print "<td> </td>"; }
251 print "</tr>\n";
252
253 rizwank 1.1 my $p_p; my $p_h;
254 if ($TotalPages) { $p_p=int($rest_p/$TotalPages*1000)/10; }
255 if ($TotalHits) { $p_h=int($rest_h/$TotalHits*1000)/10; }
256 print "<tr><td class=\"aws\"><span style=\"color: #$color_other\">$Message[2]/$Message[0]</span></td>";
257 if ($ShowRegions =~ /P/i) { print "<td>".($rest_p?$rest_p:" ")."</td>"; }
258 if ($ShowRegions =~ /P/i) { print "<td>".($rest_p?"$p_p %":' ')."</td>"; }
259 if ($ShowRegions =~ /H/i) { print "<td>".($rest_h?$rest_h:" ")."</td>"; }
260 if ($ShowRegions =~ /H/i) { print "<td>".($rest_h?"$p_h %":' ')."</td>"; }
261 if ($ShowRegions =~ /B/i) { print "<td>".Format_Bytes($rest_k)."</td>"; }
262 if ($ShowRegions =~ /L/i) { print "<td> </td>"; }
263 print "</tr>\n";
264 }
265 &tab_end();
266
267 # ----->
268 return 0;
269 }
270
271
272 #-----------------------------------------------------------------------------
273 # PLUGIN FUNCTION: ShowInfoHost_pluginname
274 rizwank 1.1 # UNIQUE: NO (Several plugins using this function can be loaded)
275 # Function called to add additionnal columns to the Hosts report.
276 # This function is called when building rows of the report (One call for each
277 # row). So it allows you to add a column in report, for example with code :
278 # print "<TD>This is a new cell for $param</TD>";
279 # Parameters: Host name or ip
280 #-----------------------------------------------------------------------------
281 sub ShowInfoHost_geoip_region_maxmind {
282 my $param="$_[0]";
283 # <-----
284 if ($param eq '__title__') {
285 my $NewLinkParams=${QueryString};
286 $NewLinkParams =~ s/(^|&)update(=\w*|$)//i;
287 $NewLinkParams =~ s/(^|&)output(=\w*|$)//i;
288 $NewLinkParams =~ s/(^|&)staticlinks(=\w*|$)//i;
289 $NewLinkParams =~ s/(^|&)framename=[^&]*//i;
290 my $NewLinkTarget='';
291 if ($DetailedReportsOnNewWindows) { $NewLinkTarget=" target=\"awstatsbis\""; }
292 if (($FrameName eq 'mainleft' || $FrameName eq 'mainright') && $DetailedReportsOnNewWindows < 2) {
293 $NewLinkParams.="&framename=mainright";
294 $NewLinkTarget=" target=\"mainright\"";
295 rizwank 1.1 }
296 $NewLinkParams =~ tr/&/&/s; $NewLinkParams =~ s/^&//; $NewLinkParams =~ s/&$//;
297 if ($NewLinkParams) { $NewLinkParams="${NewLinkParams}&"; }
298
299 print "<th width=\"80\">";
300 print "<a href=\"".($ENV{'GATEWAY_INTERFACE'} || !$StaticLinks?XMLEncode("$AWScript?${NewLinkParams}output=plugin_geoip_region_maxmind"):"$PROG$StaticLinks.plugin_geoip_region_maxmind.$StaticExt")."\"$NewLinkTarget>GeoIP<br>Region</a>";
301 print "</th>";
302 }
303 elsif ($param) {
304 my $ip=0;
305 my $key;
306 if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address
307 $ip=4;
308 $key=$param;
309 }
310 elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address
311 $ip=6;
312 $key=$param;
313 }
314 print "<td>";
315 if ($key && $ip==4) {
316 rizwank 1.1 my ($res1,$res2,$countryregion)=();
317 ($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
318 if ($Debug) { debug(" Plugin geoip_region_maxmind: GetRegionByIp for $param: [${res1}_${res2}]",5); }
319 if ($res1 =~ /\w\w/) { print $DomainsHashIDLib{lc($res1)}||uc($res1); }
320 else { print "<span style=\"color: #$color_other\">$Message[0]</span>"; }
321 if ($res1 =~ /\w\w/ && $res2 =~ /\w\w/) {
322 print " (";
323 print $region{lc($res1)}{uc($res2)};
324 print ")";
325 }
326 }
327 if ($key && $ip==6) {
328 print "<span style=\"color: #$color_other\">$Message[0]</span>";
329 }
330 if (! $key) {
331 my ($res1,$res2,$countryregion)=();
332 ($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
333 if ($Debug) { debug(" Plugin geoip_region_maxmind: GetRegionByName for $param: [${res1}_${res2}]",5); }
334 if ($res1 =~ /\w\w/) { print $DomainsHashIDLib{lc($res1)}||uc($res1); }
335 else { print "<span style=\"color: #$color_other\">$Message[0]</span>"; }
336 if ($res1 =~ /\w\w/ && $res2 =~ /\w\w/) {
337 rizwank 1.1 print " (";
338 print $region{lc($res1)}{uc($res2)};
339 print ")";
340 }
341 }
342 print "</td>";
343 }
344 else {
345 print "<td> </td>";
346 }
347 return 1;
348 # ----->
349 }
350
351
352 #-----------------------------------------------------------------------------
353 # PLUGIN FUNCTION: SectionInitHashArray_pluginname
354 # UNIQUE: NO (Several plugins using this function can be loaded)
355 #-----------------------------------------------------------------------------
356 sub SectionInitHashArray_geoip_region_maxmind {
357 my $param="$_[0]";
358 rizwank 1.1 # <-----
359 if ($Debug) { debug(" Plugin geoip_region_maxmind: Init_HashArray"); }
360 %_region_p = %_region_h = %_region_k = %_region_l =();
361 # ----->
362 return 0;
363 }
364
365
366 #-----------------------------------------------------------------------------
367 # PLUGIN FUNCTION: SectionProcessHostname_pluginname
368 # UNIQUE: NO (Several plugins using this function can be loaded)
369 #-----------------------------------------------------------------------------
370 sub SectionProcessIp_geoip_region_maxmind {
371 my $param="$_[0]"; # Param must be an IP
372 # <-----
373 my ($res1,$res2,$countryregion)=();
374 ($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
375 if ($Debug) { debug(" Plugin geoip_region_maxmind: GetRegionByIp for $param: [${res1}_${res2}]",5); }
376 if ($res2 =~ /\w\w/) { $countryregion=lc("${res1}_${res2}"); }
377 else { $countryregion='unknown'; }
378 # if ($PageBool) { $_region_p{$countryregion}++; }
379 rizwank 1.1 $_region_h{$countryregion}++;
380 # if ($timerecord > $_region_l{$countryregion}) { $_region_l{$countryregion}=$timerecord; }
381 # ----->
382 return;
383 }
384
385 #-----------------------------------------------------------------------------
386 # PLUGIN FUNCTION: SectionProcessHostname_pluginname
387 # UNIQUE: NO (Several plugins using this function can be loaded)
388 #-----------------------------------------------------------------------------
389 sub SectionProcessHostname_geoip_region_maxmind {
390 my $param="$_[0]"; # Param must be a hostname
391 # <-----
392 my ($res1,$res2,$countryregion)=();
393 ($res1,$res2)=$geoip_region_maxmind->region_by_name($param) if $geoip_region_maxmind;
394 if ($Debug) { debug(" Plugin geoip_region_maxmind: GetRegionByName for $param: [{$res1}_{$res2}]",5); }
395 if ($res2 =~ /\w\w/) { $countryregion=lc("${res1}_${res2}"); }
396 else { $countryregion='unknown'; }
397 # if ($PageBool) { $_region_p{$countryregion}++; }
398 $_region_h{$countryregion}++;
399 # if ($timerecord > $_region_l{$countryregion}) { $_region_l{$countryregion}=$timerecord; }
400 rizwank 1.1 # ----->
401 return;
402 }
403
404
405 #-----------------------------------------------------------------------------
406 # PLUGIN FUNCTION: SectionReadHistory_pluginname
407 # UNIQUE: NO (Several plugins using this function can be loaded)
408 #-----------------------------------------------------------------------------
409 sub SectionReadHistory_geoip_region_maxmind {
410 my $issectiontoload=shift;
411 my $xmlold=shift;
412 my $xmleb=shift;
413 my $countlines=shift;
414 # <-----
415 if ($Debug) { debug(" Plugin geoip_region_maxmind: Begin of PLUGIN_geoip_region_maxmind section"); }
416 my @field=();
417 my $count=0;my $countloaded=0;
418 do {
419 if ($field[0]) {
420 $count++;
421 rizwank 1.1 if ($issectiontoload) {
422 $countloaded++;
423 if ($field[2]) { $_region_h{$field[0]}+=$field[2]; }
424 }
425 }
426 $_=<HISTORY>;
427 chomp $_; s/\r//;
428 @field=split(/\s+/,($xmlold?CleanFromTags($_):$_));
429 $countlines++;
430 }
431 until ($field[0] eq 'END_PLUGIN_geoip_region_maxmind' || $field[0] eq "${xmleb}END_PLUGIN_geoip_region_maxmind" || ! $_);
432 if ($field[0] ne 'END_PLUGIN_geoip_region_maxmind' && $field[0] ne "${xmleb}END_PLUGIN_geoip_region_maxmind") { 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); }
433 if ($Debug) { debug(" Plugin geoip_region_maxmind: End of PLUGIN_geoip_region_maxmind section ($count entries, $countloaded loaded)"); }
434 # ----->
435 return 0;
436 }
437
438 #-----------------------------------------------------------------------------
439 # PLUGIN FUNCTION: SectionWriteHistory_pluginname
440 # UNIQUE: NO (Several plugins using this function can be loaded)
441 #-----------------------------------------------------------------------------
442 rizwank 1.1 sub SectionWriteHistory_geoip_region_maxmind {
443 my ($xml,$xmlbb,$xmlbs,$xmlbe,$xmlrb,$xmlrs,$xmlre,$xmleb,$xmlee)=(shift,shift,shift,shift,shift,shift,shift,shift,shift);
444 if ($Debug) { debug(" Plugin geoip_region_maxmind: SectionWriteHistory_geoip_region_maxmind start - ".(scalar keys %_region_h)); }
445 # <-----
446 print HISTORYTMP "\n";
447 if ($xml) { print HISTORYTMP "<section id='plugin_geoip_region_maxmind'><sortfor>$MAXNBOFSECTIONGIR</sortfor><comment>\n"; }
448 print HISTORYTMP "# Plugin key - Pages - Hits - Bandwidth - Last access\n";
449 #print HISTORYTMP "# The $MaxNbOfExtra[$extranum] first number of hits are first\n";
450 $ValueInFile{'plugin_geoip_region_maxmind'}=tell HISTORYTMP;
451 print HISTORYTMP "${xmlbb}BEGIN_PLUGIN_geoip_region_maxmind${xmlbs}".(scalar keys %_region_h)."${xmlbe}\n";
452 &BuildKeyList($MAXNBOFSECTIONGIR,1,\%_region_h,\%_region_h);
453 my %keysinkeylist=();
454 foreach (@keylist) {
455 $keysinkeylist{$_}=1;
456 #my $page=$_region_p{$_}||0;
457 #my $bytes=$_region_k{$_}||0;
458 #my $lastaccess=$_region_l{$_}||'';
459 print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_region_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
460 }
461 foreach (keys %_region_h) {
462 if ($keysinkeylist{$_}) { next; }
463 rizwank 1.1 #my $page=$_region_p{$_}||0;
464 #my $bytes=$_region_k{$_}||0;
465 #my $lastaccess=$_region_l{$_}||'';
466 print HISTORYTMP "${xmlrb}$_${xmlrs}0${xmlrs}", $_region_h{$_}, "${xmlrs}0${xmlrs}0${xmlre}\n"; next;
467 }
468 print HISTORYTMP "${xmleb}END_PLUGIN_geoip_region_maxmind${xmlee}\n";
469 # ----->
470 return 0;
471 }
472
473
474
475 1; # Do not remove this line
|