This queue is for tickets about the Geo-IPfree CPAN distribution.

Report information
The Basics
Id:
24333
Status:
resolved
Priority:
Low/Low
Queue:

People
Owner:
Nobody in particular
Requestors:
jasus [...] telefonica.net
Cc:
AdminCc:

BugTracker
Severity:
Important
Broken in:
0.2
Fixed in:
(no value)



Subject: 2 warnings and 2 "uninitialized value", (with solution)
Hi, in first place, sorry for my bad english. When i use the perl module: use Geo::IPfree qw(LookUp); my $ip = '80.80.80.8'; my ($country,$country_name) = Geo::IPfree::LookUp($ip); The perl interpreter show this: Possible attempt to separate words with commas at /usr/share/perl5/Geo/IPfree.pm line 38. Possible attempt to separate words with commas at /usr/share/perl5/Geo/IPfree.pm line 63. Use of uninitialized value in string eq at /usr/share/perl5/Geo/IPfree.pm line 267. Use of uninitialized value in length at /usr/share/perl5/Geo/IPfree.pm line 125. I edited the file /usr/share/perl5/Geo/IPfree.pm, and now this work without print warnings. *** 1º & 2º WARNING "Possible attempt to separate words with commas at /usr/share/perl5/Geo/IPfree.pm line 38." "Possible attempt to separate words with commas at /usr/share/perl5/Geo/IPfree.pm line 63." Replace: my @baseX = qw/ ... / ; my %countrys = qw/ ... / ; And put this (with quoted strings): my @baseX = ( ... ) ; my %countrys = ( ... ) ; *** 3º WARNING: "Use of uninitialized value in string eq at /usr/share/perl5/Geo/IPfree.pm line 267." if ($lib_path eq '') { <--- uninitialized value in string Replace: my $lib_path ; and put: my $lib_path = ''; *** 4º WARNING: "Use of uninitialized value in length at /usr/share/perl5/Geo/IPfree.pm line 125." while( read($handler, $buffer , 1 , length($buffer) ) ) { <--- uninitialized value length($buffer) In the line: my ($handler,$buffer) ; add the value (0 is valid): my ($handler,$buffer) ; $buffer=0; I attach the file edited. Byezzzzzzz
Subject: IPfree.pm
#!/usr/bin/perl -X ############################################################################# ## Name: Geo/IPfree.pm ## Purpose: Look up country of IP Address. ## Author: Graciliano M. P. ## Modified by: ## Created: 20/10/2002 ## RCS-ID: ## Copyright: (c) 2002 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# # # Laurent Destailleur improvements: # - Changed "sysread" to "read". # for cleaner code, better compatibility and to fix bug of using not always working 'tell' with 'sysread'. # - Added $this->{searchorder}, for speed improvment, avoiding sort for each lookup. # - Trap errors on open(). # package Geo::IPfree; use 5.006; use Memoize; use Carp qw() ; use strict qw(vars) ; require Exporter; our @ISA = qw(Exporter); our $VERSION = '0.2'; our @EXPORT = qw(LookUp LoadDB) ; our @EXPORT_OK = @EXPORT ; my $def_db = 'ipscountry.dat' ; my @baseX = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S', 'T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q', 'r','s','t','u','v','w','x','y','z','.',',',';',"'",'"','`','<','>','{','}','[',']','=','+','-', '~','*','@','#','%','$','&','!','?') ; my %countrys = ( '--','N/A','L0','localhost','I0','IntraNet','A1','Anonymous_Proxy','A2','Satellite_Provider', 'AD','Andorra','AE','United_Arab_Emirates','AF','Afghanistan','AG','Antigua_and_Barbuda','AI', 'Anguilla','AL','Albania','AM','Armenia','AN','Netherlands_Antilles', 'AO','Angola','AP','Asia/Pacific_Region','AQ','Antarctica','AR','Argentina','AS','American_Samoa', 'AT','Austria','AU','Australia','AW','Aruba','AZ','Azerbaijan','BA','Bosnia_and_Herzegovina','BB', 'Barbados','BD','Bangladesh', 'BE','Belgium','BF','Burkina_Faso','BG','Bulgaria','BH','Bahrain','BI','Burundi','BJ','Benin','BM', 'Bermuda','BN','Brunei_Darussalam','BO','Bolivia','BR','Brazil','BS','Bahamas','BT','Bhutan','BV', 'Bouvet_Island','BW','Botswana', 'BY','Belarus','BZ','Belize','CA','Canada','CC','Cocos_(Keeling)_Islands','CD', 'Congo,_The_Democratic_Republic_of_the','CF','Central_African_Republic','CG','Congo','CH', 'Switzerland','CI',"Cote_D'Ivoire",'CK','Cook_Islands', 'CL','Chile','CM','Cameroon','CN','China','CO','Colombia','CR','Costa_Rica','CU','Cuba','CV', 'Cape_Verde','CX','Christmas_Island','CY','Cyprus','CZ','Czech_Republic','DE','Germany','DJ', 'Djibouti','DK','Denmark','DM','Dominica', 'DO','Dominican_Republic','DZ','Algeria','EC','Ecuador','EE','Estonia','EG','Egypt','EH', 'Western_Sahara','ER','Eritrea','ES','Spain','ET','Ethiopia','EU','Europe','FI','Finland','FJ', 'Fiji','FK','Falkland_Islands_(Malvinas)', 'FM','Micronesia,_Federated_States_of','FO','Faroe_Islands','FR','France','FX','France,_Metropolitan', 'GA','Gabon','GB','United_Kingdom','GD','Grenada','GE','Georgia','GF','French_Guiana','GH', 'Ghana','GI','Gibraltar', 'GL','Greenland','GM','Gambia','GN','Guinea','GP','Guadeloupe','GQ','Equatorial_Guinea','GR', 'Greece','GS','South_Georgia_and_the_South_Sandwich_Islands','GT','Guatemala','GU','Guam','GW', 'Guinea-Bissau','GY','Guyana','HK','Hong_Kong','HM','Heard_Island_and_McDonald_Islands','HN', 'Honduras','HR','Croatia','HT','Haiti','HU','Hungary','ID','Indonesia','IE','Ireland','IL','Israel', 'IN','India','IO','British_Indian_Ocean_Territory', 'IQ','Iraq','IR','Iran,_Islamic_Republic_of','IS','Iceland','IT','Italy','JM','Jamaica','JO','Jordan', 'JP','Japan','KE','Kenya','KG','Kyrgyzstan','KH','Cambodia','KI','Kiribati','KM','Comoros','KN', 'Saint_Kitts_and_Nevis','KP',"Korea,_Democratic_People's_Republic_of",'KR','Korea,_Republic_of','KW', 'Kuwait','KY','Cayman_Islands','KZ','Kazakhstan','LA',"Lao_People's_Democratic_Republic",'LB', 'Lebanon','LC','Saint_Lucia','LI','Liechtenstein', 'LK','Sri_Lanka','LR','Liberia','LS','Lesotho','LT','Lithuania','LU','Luxembourg','LV','Latvia','LY', 'Libyan_Arab_Jamahiriya','MA','Morocco','MC','Monaco','MD','Moldova,_Republic_of MG Madagascar', 'MH','Marshall_Islands', 'MK','Macedonia,_the_Former_Yugoslav_Republic_of','ML','Mali','MM','Myanmar','MN','Mongolia','MO', 'Macau','MP','Northern_Mariana_Islands','MQ','Martinique','MR','Mauritania','MS','Montserrat','MT', 'Malta','MU','Mauritius', 'MV','Maldives','MW','Malawi','MX','Mexico','MY','Malaysia','MZ','Mozambique','NA','Namibia','NC', 'New_Caledonia','NE','Niger','NF','Norfolk_Island','NG','Nigeria','NI','Nicaragua','NL','Netherlands', 'NO','Norway','NP','Nepal', 'NR','Nauru','NU','Niue','NZ','New_Zealand','OM','Oman','PA','Panama','PE','Peru','PF','French_Polynesia', 'PG','Papua_New_Guinea','PH','Philippines','PK','Pakistan','PL','Poland','PM', 'Saint_Pierre_and_Miquelon','PN','Pitcairn', 'PR','Puerto_Rico','PS','Palestinian_Territory,_Occupied','PT','Portugal','PW','Palau','PY','Paraguay', 'QA','Qatar','RE','Reunion','RO','Romania','RU','Russian_Federation','RW','Rwanda','SA','Saudi_Arabia', 'SB','Solomon_Islands','SC','Seychelles','SD','Sudan','SE','Sweden','SG','Singapore','SH','Saint_Helena', 'SI','Slovenia','SJ','Svalbard_and_Jan_Mayen','SK','Slovakia','SL','Sierra_Leone','SM','San_Marino', 'SN','Senegal','SO','Somalia','SR','Suriname', 'ST','Sao_Tome_and_Principe','SV','El_Salvador','SY','Syrian_Arab_Republic','SZ','Swaziland','TC', 'Turks_and_Caicos_Islands','TD','Chad','TF','French_Southern_Territories','TG','Togo','TH','Thailand', 'TJ','Tajikistan', 'TK','Tokelau','TM','Turkmenistan','TN','Tunisia','TO','Tonga','TP','East_Timor','TR','Turkey','TT', 'Trinidad_and_Tobago','TV','Tuvalu','TW','Taiwan,_Province_of_China','TZ', 'Tanzania,_United_Republic_of','UA','Ukraine', 'UG','Uganda','UM','United_States_Minor_Outlying_Islands','US','United_States','UY','Uruguay','UZ', 'Uzbekistan','VA','Holy_See_(Vatican_City_State)','VC','Saint_Vincent_and_the_Grenadines','VE', 'Venezuela', 'VG','Virgin_Islands,_British','VI','Virgin_Islands,_U.S.','VN','Vietnam','VU','Vanuatu','WF', 'Wallis_and_Futuna','WS','Samoa','YE','Yemen','YT','Mayotte','YU','Yugoslavia','ZA','South_Africa', 'ZM','Zambia','ZR','Zaire','ZW','Zimbabwe' ); my (%baseX,$base,$THIS) ; my $cache_expire = 1000 ; #################### # DECLARE BASE LIB # #################### { my $c = 0 ; %baseX = map { $_ => ($c++) } @baseX ; $base = @baseX ; foreach my $Key ( keys %countrys ) { $countrys{$Key} =~ s/_/ /gs ;} } ####### # NEW # ####### sub new { my ($class, $db_file) = @_ ; if ($#_ <= 0 && $_[0] !~ /^[\w:]+$/) { $class = 'Geo::IPfree' ; $db_file = $_[0] ; } my $this = {} ; bless($this , $class) ; if (!defined $db_file) { $db_file = &find_db_file ;} $this->{dbfile} = $db_file ; $this->LoadDB($db_file) ; $this->{cache} = 1 ; return( $this ) ; } ########## # LOADDB # ########## sub LoadDB { my $this = shift ; my ( $db_file ) = @_ ; if (-d $db_file) { $db_file .= "/$def_db" ;} if (!-s $db_file) { Carp::croak("Can't load database, blank or not there: $db_file") ;} $this->{db} = $db_file ; my ($handler,$buffer) ; $buffer=0; open($handler,$db_file) || Carp::croak("Failed to open database file $db_file for read!") ; binmode($handler) ; if ( $this->{pos} ) { delete($this->{pos}) ;} while( read($handler, $buffer , 1 , length($buffer) ) ) { if ($buffer =~ /##headers##(\d+)##$/s ) { my $headers ; read($handler, $headers , $1 ) ; my (%head) = ( $headers =~ /(\d+)=(\d+)/gs ); foreach my $Key ( keys %head ) { $this->{pos}{$Key} = $head{$Key} ;} $buffer = '' ; } elsif ($buffer =~ /##start##$/s ) { $this->{start} = tell($handler) ; last ; } } @{$this->{searchorder}} = ( sort {$a <=> $b} keys %{$this->{pos}} ) ; $this->{handler} = $handler ; } ########## # LOOKUP # ########## sub LookUp { my $this ; if ($#_ == 0) { if (!$THIS) { $THIS = Geo::IPfree->new() ;} $this = $THIS ; } else { $this = shift ;} my ( $ip ) = @_ ; $ip =~ s/\.+/\./gs ; $ip =~ s/^\.// ; $ip =~ s/\.$// ; if ($ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { $ip = nslookup($ip) ;} ## Since the last class is always from the same country, will try 0 and cache 0: my $ip_class = $ip ; $ip_class =~ s/\.\d+$/\.0/ ; if ( $this->{cache} && $this->{CACHE}{$ip_class} ) { return( @{$this->{CACHE}{$ip_class}} , $ip_class ) ;} my $ipnb = ip2nb($ip_class) ; my $buf_pos = 0 ; foreach my $Key ( @{$this->{searchorder}} ) { if ($ipnb <= $Key) { $buf_pos = $this->{pos}{$Key} ; last ;} } my ($buffer,$country,$iprange) ; ## Will use the DB in the memory: if ( $this->{FASTER} ) { while($buf_pos < $this->{DB_SIZE}) { $buffer = substr($this->{DB} , $buf_pos , 7) ; $country = substr($buffer , 0 , 2) ; $iprange = baseX2dec( substr($buffer , 2 , 5) ) ; $buf_pos += 7 ; if ($ipnb >= $iprange) { last ;} } } ## Will read the DB in the disk: else { seek($this->{handler} , 0 , 0) if $] < 5.006001 ; ## Fix bug on Perl 5.6.0 seek($this->{handler} , $buf_pos + $this->{start} , 0) ; while( read($this->{handler} , $buffer , 7) ) { $country = substr($buffer , 0 , 2) ; $iprange = baseX2dec( substr($buffer , 2) ) ; if ($ipnb >= $iprange) { last ;} } } if ( $this->{cache} ) { $this->{CACHE}{$ip_class} = [$country , $countrys{$country}] ; $this->{CACHE}{x}++ ; if ( $this->{CACHE}{x} > $cache_expire ) { $this->Clean_Cache ;} } return( $country , $countrys{$country} , $ip_class ) ; } ########## # FASTER # ########## sub Faster { my $this = shift ; seek($this->{handler} , 0 , 0) ; ## Fix bug on Perl 5.6.0 seek($this->{handler} , $this->{start} , 0) ; 1 while( read($this->{handler}, $this->{DB} , 1024*4 , length($this->{DB}) ) ) ; $this->{DB_SIZE} = length($this->{DB}) ; memoize('dec2baseX') ; memoize('baseX2dec') ; ## Too many memory and not soo fast: #memoize('ip2nb') ; #memoize('nb2ip') ; $this->{FASTER} = 1 ; } ############### # CLEAN_CACHE # ############### sub Clean_Cache { delete $_[0]->{CACHE} ; 1 ;} ############ # NSLOOKUP # ############ sub nslookup { my ( $host ) = @_ ; require Socket ; my $iaddr = Socket::inet_aton($host) ; my @ip = unpack('C4',$iaddr) ; if (! @ip && ! $_[1]) { return( &nslookup("www.$host",1) ) ;} return( join (".",@ip) ) ; } ################ # FIND_DB_FILE # ################ sub find_db_file { my $lib_path = ''; foreach my $Key ( keys %INC ) { if ($Key =~ /^IPfree.pm$/i) { my ($lib) = ( $INC{$Key} =~ /^(.*?)[\\\/]+[^\\\/]+$/gs ) ; if (-e "$lib/$def_db") { $lib_path = $lib ; last ;} } } if ($lib_path eq '') { foreach my $INC_i ( @INC ) { my $lib = "$INC_i/Geo" ; if (-e "$lib/$def_db") { $lib_path = $lib ; last ;} } } if ($lib_path eq '') { foreach my $dir ( @INC , '/tmp' , '/usr/local/share' , '/usr/local/share/GeoIPfree' ) { if (-e "$dir/$def_db") { $lib_path = $dir ; last ;} } } return( "$lib_path/$def_db" ) ; } ######### # IP2NB # ######### sub ip2nb { my @ip = split(/\./ , $_[0]) ; #return( 16777216* $ip[0] + 65536* $ip[1] + 256* $ip[2] + $ip[3] ) ; return( ($ip[0]<<24) + ($ip[1]<<16) + ($ip[2]<<8) + $ip[3] ) ; } ######### # NB2IP # ######### sub nb2ip { my ( $ipn ) = @_ ; my @ip ; my $x = $ipn ; while($x > 1) { my $c = $x / 256 ; my $ci = int($x / 256) ; #push(@ip , $x - ($ci*256)) ; push(@ip , $x - ($ci<<8)) ; $x = $ci ; } push(@ip , $x) if $x > 0 ; while( $#ip < 3 ) { push(@ip , 0) ;} @ip = reverse (@ip) ; return( join (".", @ip) ) ; } ############# # DEC2BASEX # ############# sub dec2baseX { my ( $dec ) = @_ ; my @base ; my $x = $dec ; while($x > 1) { my $c = $x / $base ; my $ci = int($x / $base) ; push(@base , $x - ($ci*$base) ) ; $x = $ci ; } push(@base , $x) if $x > 0 ; while( $#base < 4 ) { push(@base , 0) ;} my $baseX ; foreach my $base_i ( reverse @base ) { $baseX .= $baseX[$base_i] ; } return( $baseX ) ; } ############# # BASEX2DEC # ############# sub baseX2dec { my ( $baseX ) = @_ ; my @base = split("" , $baseX) ; my $dec ; my $i = -1 ; foreach my $base_i ( reverse @base ) { $i++ ; $dec += $baseX{$base_i} * ($base**$i) ; } return( $dec ) ; } ####### # END # ####### 1; __END__ =head1 NAME Geo::IPfree - Look up country of IP Address. This module make this off-line and the DB of IPs is free & small. =head1 SYNOPSIS use Geo::IPfree; my ($country,$country_name) = Geo::IPfree::LookUp("192.168.0.1") ; ... or ... use Geo::IPfree qw(LookUp) ; my ($country,$country_name) = LookUp("200.176.3.142") ; ... or ... use Geo::IPfree; my $GeoIP = Geo::IPfree->new('/GeoIPfree/ipscountry.dat') ; $GeoIP->Faster ; ## Enable the faster option. my ($country,$country_name,$ip) = $GeoIP->LookUp("www.cnn.com") ; ## Getting by Hostname. $GeoIP->LoadDB('/GeoIPfree/ips.dat') ; my ($country,$country_name,$ip) = $GeoIP->LookUp("www.sf.net") ; ## Getting by Hostname. ... or ... use Geo::IPfree; my $GeoIP = Geo::IPfree::new() ; ## Using the default DB! my ($country,$country_name) = $GeoIP->LookUp("64.236.24.28") ; =head1 DESCRIPTION This package comes with it's own database to look up the IP's country, and is totally free. Take a look in CPAN for updates... =head1 METHODS =over 4 =item LoadDB Load the database to use to LookUp the IPs. =item LookUp Returns the ISO 3166 country (XX) code for an IP address or Hostname. **If you send a Hostname you will need to be connected to the internet to resolve the host IP. =item Clean_Cache Clean the memory used by the cache. =item Faster Make the LookUp() faster, good for big amount of LookUp()s. This will load all the DB in the memory (200Kb) and read from there, not from HD (good way for slow HD or network disks), but use more memory. The module "Memoize" will be enabled for some internal functions too. Note that if you make a big amount of querys to LookUp(), in the end the amount of memory can be big, than is better to use more memory from the begin and make all faster. =back =head1 VARS =over 4 =item $GeoIP->{db} The database file in use. =item $GeoIP->{handler} The database file handler. =item $GeoIP->{dbfile} The database file path. =item $GeoIP->{cache} BOOLEAN Set/tell if the cache of LookUp() is on. If it's on it will cache the last 1000 querys. Default: 1 The cache is good when you are parsing a list of IPs, generally a web log. If in the log you have many lines with the same IP, GEO::IPfree don't need to make a full search for each query, it will cache the last 1000 different IPs. After each 1000 IPs the cache is cleaned to restart it. Note that the Lookup make the query without the last IP number (xxx.xxx.xxx.0), then the cache for the IP 192.168.0.1 will be the same for 192.168.0.2 (they are the same query, 192.168.0.0). =back =head1 DB FORMAT the DB has a list of IP ranges & countrys, for example, from 200.128.0.0 to 200.103.255.255 the IPs are from BR. To make a fast access to the DB the format try to use less bytes per input (block). The file was in ASCII and in blocks of 7 bytes: XXnnnnn XX -> the country code (BR,US...) nnnnn -> the IP range using a base of 85 digits (not in dec or hex to get space). See CPAN for updates of the DB... =head1 NOTES The file ipscountry.dat is made only for Geo::IPfree and has their own format. To convert it see the tool "ipct2txt.pl" in the same path of Geo/IPfree.pm. =head1 CHAGES 0.2 - Sat Mar 22 18:10 2003 - Change sysread() to read() for better portability. - Speed improvement for multiples LookUp(). 4 times faster! 0.01.1 - Nov 6 14:05:03 2002 (not released on CPAN) - Fix seek bug for Perl 5.6.0 on multiples LookUp(). =head1 AUTHOR Graciliano M. P. <gm@virtuasites.com.br>. Thanks to Laurent Destailleur (author of AWStats) that tested it on many OS and fixed bugs for them, like the not portable sysread, and asked for some speed improvement. =head1 COPYRIGHT This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut
All of the warnings have been eliminated in version 0.3


This service runs on Request Tracker, is sponsored by The Perl Foundation, and maintained by Best Practical Solutions.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.