file/cwhois.php
<?php
define("E_FCW_WRONG_DATA_FILENAME", 1);
define("E_FCW_WRONG_XML_FILENAME", 2);
define("E_FCW_WRONG_DATA_FILE", 11);
define("E_FCW_WRONG_XML_FILE", 12);
define("E_FCW_WRONG_ADDR_FORMAT", 21);
define("E_FCW_WRONG_ADDR", 31);
define("E_FCW_WRONG_ADDR_LONG", 32);
define("FCW_DATAROW_LENGTH", 10);
class CFileCWhois
{
var $dataFileName = "";
var $dataFile = NULL;
var $xmlFileName = "";
var $xmlFile = NULL;
var $error = NULL;
var $errReports = NULL;
var $parser = NULL;
var $pow8;
var $pow16;
var $pow24;
function _setError($errCode, $method, $line, $file, $additionalInfo = "")
{
$this->error->clean();
$text = "Error #".$errCode." in ".get_class($this)."::".$method.", file ".$file."\n".$additionalInfo."\n";
$text.= print_r($this, true);
$this->error->setError($errCode, $this->errReports[$errCode], $text);
}
function getLastErrorCode()
{
return $this->error->getCode();
}
function getLastError()
{
return $this->error->getString();
}
function getLastErrorText()
{
return $this->error->getDebugText();
}
function _search($addr, $start = -1, $end = -1)
{
global $iterCnt;
if ($start < 0) {
$start = 0;
$end = (int)(filesize($this->dataFileName) / FCW_DATAROW_LENGTH);
}
if ($start == $end) {
return $this->_getIdByNum($start);
}
if (($end - $start) == 1) {
fseek($this->dataFile, $start * FCW_DATAROW_LENGTH, SEEK_SET);
$str = fread($this->dataFile, 10);
if (($addr >= (((ord($str[0])*256+ord($str[1]))*256+ord($str[2]))*256+ord($str[3]))) && ($addr <= (((ord($str[4])*256+ord($str[5]))*256+ord($str[6]))*256+ord($str[7])))) {
return $this->_getIdByNum($start);
}
fseek($this->dataFile, $end * FCW_DATAROW_LENGTH, SEEK_SET);
$str = fread($this->dataFile, 10);
if (($addr >= (((ord($str[0])*256+ord($str[1]))*256+ord($str[2]))*256+ord($str[3]))) && ($addr <= (((ord($str[4])*256+ord($str[5]))*256+ord($str[6]))*256+ord($str[7])))) {
return $this->_getIdByNum($end);
}
return 0;
}
$num = (int)(($start + $end) / 2);
fseek($this->dataFile, $num * FCW_DATAROW_LENGTH, SEEK_SET);
$str = fread($this->dataFile, 10);
if ($addr < (((ord($str[0])*256+ord($str[1]))*256+ord($str[2]))*256+ord($str[3]))) {
return $this->_search($addr, $start, $num);
}
if ($addr > (((ord($str[4])*256+ord($str[5]))*256+ord($str[6]))*256+ord($str[7]))) {
return $this->_search($addr, $num, $end);
}
return $this->_getIdByNum($num);
}
function _getIdByNum($num)
{
fseek($this->dataFile, $num * FCW_DATAROW_LENGTH + 8, SEEK_SET);
$str = fread($this->dataFile, 2);
return (ord($str[1])*256+ord($str[0]));
}
function _getCountryById($id)
{
}
function CFileCWhois()
{
$this->parser = & new CFileCWhoisXmlParser();
$this->error = & new CFileCWhoisError();
$errorReports = Array();
include(dirname(__FILE__)."/config.php");
$this->errReports = $errorReports;
$this->pow8 = pow(2,8);
$this->pow16 = $this->pow8 * $this->pow8;
$this->pow24 = $this->pow16 * $this->pow8;
}
function connect($dataFileName, $xmlFileName)
{
if (!empty($this->dataFile) || !empty($this->xmlFile)) {
$this->disconnect();
}
$this->dataFileName = $dataFileName;
$this->xmlFileName = $xmlFileName;
if (!is_file($this->dataFileName)) {
$this->_setError(E_FCW_WRONG_DATA_FILENAME, __FUNCTION__, __LINE__, __FILE__);
return false;
}
if (!is_file($this->xmlFileName)) {
$this->_setError(E_FCW_WRONG_XML_FILENAME, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$this->dataFile = fopen($this->dataFileName, "rb");
if (!$this->dataFile) {
$this->_setError(E_FCW_WRONG_DATA_FILE, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$this->xmlFile = fopen($this->xmlFileName, "rb");
if (!$this->xmlFile) {
$this->_setError(E_FCW_WRONG_XML_FILE, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$this->parser->parse($this->xmlFile);
return true;
}
function disconnect()
{
fclose($this->dataFile);
fclose($this->xmlFile);
}
function getCountryByAddr($addr)
{
if (is_array($addr)) {
$resArr = array();
foreach ($addr as $val) {
$resArr[] = $this->getCountryByAddr($val);
}
return $resArr;
}
if (!is_string($addr)) {
$this->_setError(E_FCW_WRONG_ADDR_FORMAT, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$addr = trim($addr);
if (!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $addr)) {
$host = getHostByName($addr);
if ($host == $addr) {
$this->_setError(E_FCW_WRONG_ADDR, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$addr = $host;
}
$addr = sprintf("%u", ip2long($addr));
if ($addr < 0) {
$this->_setError(E_FCW_WRONG_ADDR_LONG, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$id = $this->_search($addr);
return array($this->parser->getCode($id), $this->parser->getName($id));
}
function getNameByAddr($addr)
{
if (is_array($addr)) {
$resArr = array();
foreach ($addr as $val) {
$resArr[] = $this->getCountryByAddr($val);
}
return $resArr;
}
if (!is_string($addr)) {
$this->_setError(E_FCW_WRONG_ADDR_FORMAT, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$addr = trim($addr);
if (!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $addr)) {
$host = getHostByName($addr);
if ($host == $addr) {
$this->_setError(E_FCW_WRONG_ADDR, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$addr = $host;
}
$addr = sprintf("%u", ip2long($addr));
if ($addr < 0) {
$this->_setError(E_FCW_WRONG_ADDR_LONG, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$id = $this->_search($addr);
return $this->parser->getName($id);
}
function getCodeByAddr($addr)
{
if (is_array($addr)) {
$resArr = array();
foreach ($addr as $val) {
$resArr[] = $this->getCountryByAddr($val);
}
return $resArr;
}
if (!is_string($addr)) {
$this->_setError(E_FCW_WRONG_ADDR_FORMAT, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$addr = trim($addr);
if (!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $addr)) {
$host = getHostByName($addr);
if ($host == $addr) {
$this->_setError(E_FCW_WRONG_ADDR, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$addr = $host;
}
$addr = sprintf("%u", ip2long($addr));
if ($addr < 0) {
$this->_setError(E_FCW_WRONG_ADDR_LONG, __FUNCTION__, __LINE__, __FILE__);
return false;
}
$id = $this->_search($addr);
return $this->parser->getCode($id);
}
}
class CFileCWhoisXmlParser
{
var $codes;
var $countries;
var $curId = 0;
function CFileCWhoisXmlParser()
{
$codes = array();
$countries = array();
}
function startElement($parser, $name, $attrs)
{
if ("COUNTRY" == $name) {
$this->curId = $attrs["ID"];
$this->codes[$this->curId] = $attrs["CODE"];
}
}
function endElement($parser, $name)
{
if ("COUNTRY" == $name) {
$this->curId = 0;
}
}
function charData($parser, $data)
{
$this->countries[$this->curId] = $data;
}
function parse($fp)
{
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($xml_parser, array(&$this,"startElement"), array(&$this,"endElement"));
xml_set_character_data_handler($xml_parser, array(&$this,"charData"));
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser)));
}
}
xml_parser_free($xml_parser);
}
function getCode($id)
{
if (!array_key_exists($id, $this->codes)) {
return '';
}
return $this->codes[$id];
}
function getName($id)
{
if (!array_key_exists($id, $this->countries)) {
return 'Unknown';
}
return $this->countries[$id];
}
}
class CFileCWhoisError
{
var $errCode = 0;
var $errStr = "";
var $errDebugText = "";
function setError($code, $str, $text)
{
$this->errCode = $code;
$this->errStr = $str;
$this->errDebugText = $text;
}
function clean()
{
$this->errCode = 0;
$this->errStr = "";
$this->errDebugText = "";
}
function getCode()
{
return $this->errCode;
}
function getString()
{
return $this->errStr;
}
function getDebugText()
{
return $this->errDebugText;
}
}
?>
file/config.php
<?php
$errorReports[E_FCW_WRONG_DATA_FILENAME] = "Non existing data file";
$errorReports[E_FCW_WRONG_XML_FILENAME] = "Non existing xml file";
$errorReports[E_FCW_WRONG_DATA_FILE] = "Can't open data file";
$errorReports[E_FCW_WRONG_XML_FILE] = "Can't open xml file";
$errorReports[E_FCW_WRONG_ADDR_FORMAT] = "Wrong address format";
$errorReports[E_FCW_WRONG_ADDR] = "Wrong address";
$errorReports[E_FCW_WRONG_ADDR_LONG] = "Can't convert ip to long";
?>