<?php
/*
*
* Copyright (C) 2008 Volkan KIRIK
*
*/
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
class server_met_parser {
var $fp;
var $ed2k_servers;
var $errlog = array();
var $slimit = 500;
function ireadch ($fp, $number, $cast=true) {
$c = '';
do $c.= fgetc($fp); while (--$number);
if (!$cast) {
return $c;
}
return (int)$c;
}
function lreadch ($fp, $number, $cast=true) {
$c = '';
do $c.= ord(fgetc($fp)); while (--$number);
if (!$cast) {
return $c;
}
return (int)$c;
}
function readlong ($fp) {
if (!$fp) {
return NULL;
}
$c = ord(fgetc($fp));
$c |= (ord(fgetc($fp)) << 8);
$c |= (ord(fgetc($fp)) << 16);
$c |= (ord(fgetc($fp)) << 24);
return (int)$c;
}
function strtoascii($string, $reverse=false) {
$strlength = strlen($string);
$retString = '';
for($i = 0; $i < $strlength; $i++){
if (!$reverse) {
$retString .= ord($string[$i]);
} else {
$ch_3 = substr($string,$i,3);
$ch_2 = substr($string,$i,2);
// ascii values of d-z characters are between 100-122
if ( ($ch_3 <= 122) && ($ch_3 >= 100) ) {
$retString .= chr($ch_3);
$i++;
}
// ascii values of 0-9 characters are between 48-57
// ascii values of A-Z characters are between 65-90
else {
$retString .= chr($ch_2);
}
$i++;
}
}
return $retString;
}
function isDecimalNumber($n) {
return (string)(float)$n === (string)$n;
}
function setlimit($n) {
if ( empty($n) || !is_numeric($n) || ($n <= 0) ) {
return false;
}
$this->slimit = $n;
}
function openfile($filename) {
$this->fp = fopen($filename, 'r');
if ( !$this->fp ) {
return false;
}
return true;
}
function closefile() {
@fclose($this->fp);
}
function parsefile($filename) {
if ( !$this->openfile($filename) ) {
$this->errlog[] = 'File Open Failed';
return false;
}
$validate = $this->lreadch($this->fp,1);
if ( ($validate!=hexdec('0x0E')) && ($validate!=hexdec('0xE0')) ) {
$this->errlog[] = 'File Validate Failed';
return false;
}
$serversf = 0;
$serversf = $this->readlong($this->fp);
$serversc = 0;
$this->ed2k_servers = array();
while( ($serversc < $serversf) && $this->fp && ($serversc < $this->slimit) ) {
for ($icount=0;$icount<4;$icount++){
$ip[$icount]=ord(fgetc($this->fp));
}
$port = ord(fgetc($this->fp));
$port |= (ord(fgetc($this->fp)) << 8);
$meta = $this->readlong($this->fp);
$ip_addr = sprintf('%u.%u.%u.%u', $ip[0],$ip[1],$ip[2],$ip[3]);
$port = sprintf('%ld', $port);
// print $ip_addr . ':' . $port . "\n\n"; // for testing
// Create new element in array with IP Addr & Port
$this->ed2k_servers[] = array('addr' => $ip_addr, 'port' => $port);
// Get Server ID
$server_id = count($this->ed2k_servers) - 1;
// Create new element for Block of Tags
$this->ed2k_servers[$server_id]['tags'] = array();
for ($lcount=0;$lcount<$meta;$lcount++) {
$t_type = intval(ord(fgetc($this->fp))); // Tag type
$t_length = ord(fgetc($this->fp)); // Name Length
$t_length |= (ord(fgetc($this->fp)) << 8);
if ($t_length==='EOF') {
exit(0);
}
if ($t_length) { // Tag Name
$t_name_code = $this->lreadch($this->fp,$t_length,false);
if ( $this->isDecimalNumber($t_name_code) ) {
$tag_id = dechex($t_name_code);
} else {
$tag_id = $this->strtoascii($t_name_code, true);
}
$t_name = '?';
switch ($t_name_code) {
case $this->strtoascii('files'):
$t_name = 'Files';
$t_name_type = 'ascii';
break;
case $this->strtoascii('users'):
$t_name = 'Users';
$t_name_type = 'ascii';
break;
case $this->strtoascii('lowusers'):
$t_name = 'Low_Users';
$t_name_type = 'ascii';
break;
case $this->strtoascii('maxusers'):
$t_name = 'Max_Users';
$t_name_type = 'ascii';
break;
case hexdec('0x87'):
$t_name = 'Max_Users';
$t_name_type = 'unicode';
break;
case hexdec('0x01'):
$t_name = 'Server_Name';
$t_name_type = 'unicode';
break;
case hexdec('0x0B'):
$t_name = 'Description';
$t_name_type = 'unicode';
break;
case hexdec('0x0C'):
$t_name = 'Ping';
$t_name_type = 'unicode';
break;
case hexdec('0x0D'):
$t_name = 'Fail';
$t_name_type = 'unicode';
break;
case hexdec('0x0E'):
$t_name = 'Preference';
$t_name_type = 'unicode';
break;
case hexdec('0x85'):
$t_name = 'DNS';
$t_name_type = 'unicode';
break;
case hexdec('0x88'):
$t_name = 'Soft_Files';
$t_name_type = 'unicode';
break;
case hexdec('0x89'):
$t_name = 'Hard_Files';
$t_name_type = 'unicode';
break;
case hexdec('0x90'):
$t_name = 'Last_Ping';
$t_name_type = 'unicode';
break;
case hexdec('0x91'):
$t_name = 'Version';
$t_name_type = 'unicode';
break;
case hexdec('0x92'):
$t_name = 'UDP_Flags';
$t_name_type = 'unicode';
break;
case hexdec('0x93'):
$t_name = 'Auxiliary_Ports';
$t_name_type = 'unicode';
break;
case hexdec('0x94'):
$t_name = 'LowID_Clients';
$t_name_type = 'unicode';
break;
default:
$t_name = '-';
$t_name_type = 'unknown';
break;
}
// echo 'Tag Name: ' . $t_name . "\n";
}
if ($t_type==2) { // String Tag
$t_length = ord(fgetc($this->fp)); // Value Length
$t_length |= (ord(fgetc($this->fp)) << 8);
if ($t_length==='EOF') {
break;
}
if ($t_length) {
$t_value = $this->ireadch($this->fp,$t_length,false);
// echo 'Tag Value (string): ' . $t_value . "\n";
} // else jump over
} else if ($t_type==3) { // Number Tag
$t_value = $this->readlong($this->fp);
$t_value = intval($t_value);
// echo 'Tag Value (integer): ' . $t_value . "\n";
}
// echo "\n";
if ( isset($this->ed2k_servers[$server_id]['tags'][$t_name.'_'.$t_name_type]) ) {
$this->ed2k_servers[$server_id]['tags'][$t_name.'_'.$t_name_type.'_2'] = array('id' => $tag_id, 'value' => $t_value);
} else {
$this->ed2k_servers[$server_id]['tags'][$t_name.'_'.$t_name_type] = array('id' => $tag_id, 'value' => $t_value);
}
}//rof
$serversc++;
}
return $this->ed2k_servers;
}
}
?>
|