4e7b397db51db27f6c90418af607eea08d551452
[moodle.git] / lib / geoip / geoipcity.inc
1 <?php
3 /* geoipcity.inc
4  *
5  * Copyright (C) 2004 Maxmind LLC
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
20  */
22 /*
23  * Changelog:
24  *
25  * 2005-01-13   Andrew Hill, Awarez Ltd. (http://www.awarez.net)
26  *              Formatted file according to PEAR library standards.
27  *              Changed inclusion of geoip.inc file to require_once, so that
28  *                  this library can be used in the same script as geoip.inc.
29  */
31 define("FULL_RECORD_LENGTH",50);
33 require_once 'geoip.inc';
34 require_once 'geoipregionvars.php';
36 class geoiprecord {
37   var $country_code;
38   var $country_code3;
39   var $country_name;
40   var $region;
41   var $city;
42   var $postal_code;
43   var $latitude;
44   var $longitude;
45   var $area_code;
46   var $dma_code;   # metro and dma code are the same. use metro_code
47   var $metro_code;
48   var $continent_code;
49 }
51 class geoipdnsrecord {
52   var $country_code;
53   var $country_code3;
54   var $country_name;
55   var $region;
56   var $regionname;
57   var $city;
58   var $postal_code;
59   var $latitude;
60   var $longitude;
61   var $areacode;
62   var $dmacode;
63   var $isp;
64   var $org;
65   var $metrocode;
66 }
68 function getrecordwithdnsservice($str){
69   $record = new geoipdnsrecord;
70   $keyvalue = explode(";",$str);
71   foreach ($keyvalue as $keyvalue2){
72     list($key,$value) = explode("=",$keyvalue2);
73     if ($key == "co"){
74       $record->country_code = $value;
75     }
76     if ($key == "ci"){
77       $record->city = $value;
78     }
79     if ($key == "re"){
80       $record->region = $value;
81     }
82     if ($key == "ac"){
83       $record->areacode = $value;
84     }
85     if ($key == "dm" || $key == "me" ){
86       $record->dmacode   = $value;
87       $record->metrocode = $value;
88     }
89     if ($key == "is"){
90       $record->isp = $value;
91     }
92     if ($key == "or"){
93       $record->org = $value;
94     }
95     if ($key == "zi"){
96       $record->postal_code = $value;
97     }
98     if ($key == "la"){
99       $record->latitude = $value;
100     }
101     if ($key == "lo"){
102       $record->longitude = $value;
103     }
104   }
105   $number = $GLOBALS['GEOIP_COUNTRY_CODE_TO_NUMBER'][$record->country_code];
106   $record->country_code3 = $GLOBALS['GEOIP_COUNTRY_CODES3'][$number];
107   $record->country_name = $GLOBALS['GEOIP_COUNTRY_NAMES'][$number];
108   if ($record->region != "") {
109     if (($record->country_code == "US") || ($record->country_code == "CA")){
110       $record->regionname = $GLOBALS['ISO'][$record->country_code][$record->region];
111     } else {
112       $record->regionname = $GLOBALS['FIPS'][$record->country_code][$record->region];
113     }
114   }
115   return $record;
118 function _get_record($gi,$ipnum){
119   $seek_country = _geoip_seek_country($gi,$ipnum);
120   if ($seek_country == $gi->databaseSegments) {
121     return NULL;
122   }
123   
124   // workaround php's broken substr, strpos, etc handling with
125   // mbstring.func_overload and mbstring.internal_encoding
126   $enc = mb_internal_encoding();
127   mb_internal_encoding('ISO-8859-1'); 
129   $record_pointer = $seek_country + (2 * $gi->record_length - 1) * $gi->databaseSegments;
130   
131   if ($gi->flags & GEOIP_MEMORY_CACHE) {
132     $record_buf = substr($gi->memory_buffer,$record_pointer,FULL_RECORD_LENGTH);
133   } elseif ($gi->flags & GEOIP_SHARED_MEMORY){
134     $record_buf = @shmop_read($gi->shmid,$record_pointer,FULL_RECORD_LENGTH);
135   } else {
136     fseek($gi->filehandle, $record_pointer, SEEK_SET);
137     $record_buf = fread($gi->filehandle,FULL_RECORD_LENGTH);
138   }
139   $record = new geoiprecord;
140   $record_buf_pos = 0;
141   $char = ord(substr($record_buf,$record_buf_pos,1));
142     $record->country_code = $gi->GEOIP_COUNTRY_CODES[$char];
143     $record->country_code3 = $gi->GEOIP_COUNTRY_CODES3[$char];
144     $record->country_name = $gi->GEOIP_COUNTRY_NAMES[$char];
145   $record->continent_code = $gi->GEOIP_CONTINENT_CODES[$char];
146   $record_buf_pos++;
147   $str_length = 0;
148     // Get region
149   $char = ord(substr($record_buf,$record_buf_pos+$str_length,1));
150   while ($char != 0){
151     $str_length++;
152     $char = ord(substr($record_buf,$record_buf_pos+$str_length,1));
153   }
154   if ($str_length > 0){
155     $record->region = substr($record_buf,$record_buf_pos,$str_length);
156   }
157   $record_buf_pos += $str_length + 1;
158   $str_length = 0;
159     // Get city
160   $char = ord(substr($record_buf,$record_buf_pos+$str_length,1));
161   while ($char != 0){
162     $str_length++;
163     $char = ord(substr($record_buf,$record_buf_pos+$str_length,1));
164   }
165   if ($str_length > 0){
166     $record->city = substr($record_buf,$record_buf_pos,$str_length);
167   }
168   $record_buf_pos += $str_length + 1;
169   $str_length = 0;
170     // Get postal code
171   $char = ord(substr($record_buf,$record_buf_pos+$str_length,1));
172   while ($char != 0){
173     $str_length++;
174     $char = ord(substr($record_buf,$record_buf_pos+$str_length,1));
175   }
176   if ($str_length > 0){
177     $record->postal_code = substr($record_buf,$record_buf_pos,$str_length);
178   }
179   $record_buf_pos += $str_length + 1;
180   $str_length = 0;
181     // Get latitude and longitude
182   $latitude = 0;
183   $longitude = 0;
184   for ($j = 0;$j < 3; ++$j){
185     $char = ord(substr($record_buf,$record_buf_pos++,1));
186     $latitude += ($char << ($j * 8));
187   }
188   $record->latitude = ($latitude/10000) - 180;
189   for ($j = 0;$j < 3; ++$j){
190     $char = ord(substr($record_buf,$record_buf_pos++,1));
191     $longitude += ($char << ($j * 8));
192   }
193   $record->longitude = ($longitude/10000) - 180;
194   if (GEOIP_CITY_EDITION_REV1 == $gi->databaseType){
195     $metroarea_combo = 0;
196     if ($record->country_code == "US"){
197       for ($j = 0;$j < 3;++$j){
198         $char = ord(substr($record_buf,$record_buf_pos++,1));
199         $metroarea_combo += ($char << ($j * 8));
200       }
201       $record->metro_code = $record->dma_code = floor($metroarea_combo/1000);
202       $record->area_code = $metroarea_combo%1000;
203     }
204   }
205   mb_internal_encoding($enc);
206   return $record;
209 function GeoIP_record_by_addr ($gi,$addr){
210   if ($addr == NULL){
211      return 0;
212   }
213   $ipnum = ip2long($addr);
214   return _get_record($gi, $ipnum);
217 ?>