public $VENDOR_CODE_MATCHINGS = array( //Vendor code conversions for matching to client names and URLs.
//URLs are optional to add ino the conversions, just replace with a false statement before doing.
//(vendor code)=>array((Actual name), (URL or put a boolean false))
'ACQL'=>array('Acqlite','http://acqlite.sourceforge.net/'),
'ACQX'=>array('Acquisition','http://www.acquisitionx.com/'),
'AGIO'=>array('Adagio','http://sourceforge.net/projects/agio'),
'BAZK'=>array('Bazooka','http://www.bazookanetworks.com/'),
'BCON'=>array('Beacon Cache','http://sourceforge.net/projects/beaconcache/'),
'BEAR'=>array('BearShare','http://en.wikipedia.org/wiki/BearShare'),
'CABO'=>array('Cabos/LimeWire','http://cabos.sourceforge.jp/'),
'CANN'=>array('Cannon',false),
'CHTC'=>array('Cheater Cache',false),
'COCO'=>array('CocoGnut','http://www.alpha-programming.co.uk/software/cocognut/'),
'DNET'=>array('Deepnet Explorer','http://www.deepnetexplorer.com/'),
'Dianlei'=>array('Dianlei','http://www.dianlei.com/'),
'dianlei'=>array('Dianlei','http://www.dianlei.com/'),
'FLOX'=>array('Flox','http://sourceforge.net/projects/flox/'),
'FOXY'=>array('Foxy P2P','http://tw.gofoxy.net/'),
'FTWC'=>array('FTWebCache',false),
'GCII'=>array('PHPGnuCacheII','http://gwcii.sourceforge.net/'),
'GDNA'=>array('GnucDNA','http://www.gnucleus.com/GnucDNA/'),
'GIFT'=>array('giFT','http://gift.sourceforge.net/'),
'GNZL'=>array('Gnoozle',false),
'GNUC'=>array('Gnucleus','http://www.gnucleus.com/Gnucleus/'),
'GNUT'=>array('Gnut','http://www.mrob.com/gnut/'),
'GOLD'=>array('Ares Gold','http://www.aresgold.com/'),
'GTKG'=>array('GTK Gnutella','http://gtk-gnutella.sourceforge.net/'),
'GWCC'=>array('Cheater Cache',false),
'iswip'=>array('iSwipe','http://www.hillmanminx.net/iswipe/'),
'JGWC'=>array('Jums Web Cache','http://www1.mager.org/GWebCache/'),
'JTEL'=>array('JTella','http://jtella.sourceforge.net/'),
'KIWI'=>array('Kiwi Alpha','http://www.kiwialpha.com/'),
'KUPE'=>array('Kupe',false),
'LIME'=>array('LimeWire','http://limewire.com/'),
'MESH'=>array('iMesh','http://en.wikipedia.org/wiki/IMesh'),
'MLDK'=>array('MLDonkey','http://mldonkey.sourceforge.net/Main_Page'),
'MMMM'=>array('Morpheus','http://www.morpheus.com/'),
'MNAP'=>array('MyNapster','http://mynapster.sourceforge.net/'),
'MRPH'=>array('Morpheus','http://www.morpheus.com/'),
'MTLL'=>array('Mutella','http://mutella.sourceforge.net/'),
'mutekomm'=>array('Kommute','http://kommute.sourceforge.net/'),
'MUTEkomm'=>array('Kommute','http://kommute.sourceforge.net/'),
'MUTE'=>array('MUTE','http://mute-net.sourceforge.net/'),
'NOVA'=>array('Nova P2P','http://novap2p.sourceforge.net/'),
'PEER'=>array('Peer Project','http://sourceforge.net/projects/peerproject/'),
'PGII'=>array('Pocket G2',false),
'PHEX'=>array('Phex','http://www.phex.org/'),
'PNTH'=>array('Panthera Project','http://pantheraproject.sourceforge.net/'),
'QTEL'=>array('Qtella','http://qtella.sourceforge.net/'),
'RAZA'=>array('Shareaza','http://shareaza.sourceforge.net/'),
'RAZB'=>array('Shareaza Beta','http://shareaza.sourceforge.net/'),
'RAZL'=>array('ShareazaLite',false),
'RZCA'=>array('ShareazaPlus (Alpha)','http://shareazaplus.sourceforge.net/'),
'RZCB'=>array('ShareazaPlus (Beta)','http://shareazaplus.sourceforge.net/'),
'RZCC'=>array('ShareazaPlus','http://shareazaplus.sourceforge.net/'),
'Self-Add'=>array('Cache Retry System',false),
'Sharetastic'=>array('Sharetastic','http://goforsharing.com/index.php/home-mainmenu-1/sharetastic-mainmenu-126'),
'SHLN-DEV'=>array('Sharelin','http://sharelin.sourceforge.net/'),
'SHLN'=>array('Sharelin','http://sharelin.sourceforge.net/'),
'SKLL'=>array('Skulls','http://sourceforge.net/projects/skulls/'),
'SNOW'=>array('Frostwire','http://www.frostwire.com/'),
'SWAP'=>array('Swapper','http://www.revolutionarystuff.com/swapper/'),
'TESTBazooka'=>array('Bazooka GWC','http://www.bazookanetworks.com/'),
'TESTBCII'=>array('Beacon Cache II','http://sourceforge.net/projects/beaconcache/'),
'TESTBCON'=>array('Beacon Cache','http://sourceforge.net/projects/beaconcache/'),
'TESTCachechu'=>array('Cachechu','http://code.google.com/p/cachechu/'),
'TESTCrab-'=>array('GhostWhiteCrab','http://wiki.limewire.org/index.php?title=GhostWhiteCrab'),
'TESTGWCSCANNER'=>array('Multi-Network GWC Scan','http://gcachescan.grantgalitz.com/'),
'TESTPGDBScan'=>array('Jon Atkins GWC Scan','http://gcachescan.jonatkins.com/'),
'TESTSKLL'=>array('Skulls','http://sourceforge.net/projects/skulls/'),
'TFLS'=>array('TrustyFiles','http://www.trustyfiles.com/'),
'URL-ADD'=>array('URL-ADD',false),
'WURM'=>array('Wurm GWC Scanner','http://kevogod.trillinux.org/')
);
}
/////////////////////////////////////////////END Settings
abstract class data_system {
public $contents; //Raw unedited output.
public $output; //Edited and 'prepped' output.
protected $runtime; //Container for passed variables.
protected $file; //The unique physical file-name that carries the requested data.
protected $name; //The unique physical name that carries the requested data (For MySQL).
protected $refresh; //Used by the stats to prevent a stat-write for read only.
protected $expire; //Time (in hours) for which a host cannot be older than.
protected $maximum; //Maximum count stored.
function __construct($runtime) {
$this->runtime = $runtime; //Container for passed variables
$this->name = $this->runtime->ID.$this->runtime->network;
$this->file = settings::FOLDER.'/'.$this->name.'.dat';
if ($this->runtime->ID == 'log' || strtolower(settings::STORAGE) == 'flat') {
if (!file_exists(settings::FOLDER)) {
mkdir(settings::FOLDER); //Create the folder
}
}
if ($this->runtime->ID != 'log' && strtolower(settings::STORAGE) == 'flat') { $this->check_exists($this->file); }
$this->refresh = false;
switch ($this->runtime->ID) { ////Run consistency checks
case 'ip': //IP consistency check
$this->expire = settings::EXPIRE_HOSTS;
$this->maximum = settings::HOSTS_IN;
break;
case 'bad_url': //banned-URL consistency check
$this->expire = settings::EXPIRE_BANNED_URLS;
$this->maximum = settings::BANNED_URLS_IN;
break;
case 'retry': //Retry-URL consistency check
case 'url': //URL consistency check
$this->expire = settings::EXPIRE_URLS;
$this->maximum = settings::URLS_IN;
}
switch ($this->runtime->flow) {
case 'up': //An update
files::update();
break;
case 'down': //Data retrieval
files::request();
}
}
protected function request() {
switch ($this->runtime->ID) { //Decide what data to retrieve.
case 'ip':
$this->ip_request();
break;
case 'retry':
$this->url_retry();
break;
case 'bad_url':
case 'url':
$this->url_request();
break;
case 'stats_total_requests':
case 'stats_total_updates':
case 'stats_client':
$this->contents = $this->grab();
break;
case 'stats_requests':
case 'stats_updates':
$this->refresh = true;
$this->update_stats();
$this->refresh = false;
$this->contents = $this->grab();
}
}
protected function update() {
switch ($this->runtime->ID) { //Decide what data to update.
case 'ip':
$this->ip_update();
break;
case 'bad_url':
case 'url':
$this->url_update();
break;
case 'log':
$this->log_update();
break;
case 'stats_total_requests':
case 'stats_total_updates':
case 'stats_client':
case 'stats_requests':
case 'stats_updates':
$this->update_stats();
}
}
protected function ip_request() {
$this->all_requests(settings::SHUFFLE_HOSTS, settings::HOSTS_OUT);
}
protected function ip_update() {
$this->add();
}
protected function url_request() {
$this->all_requests(settings::SHUFFLE_URLS, settings::URLS_OUT);
}
protected function url_update() {
$this->add();
}
protected function check_exists($name) {
if (!file_exists($name)) {
$file = fopen($name, 'wb');
fclose($file);
}
}
protected function log_update() {
$log_marker = 0;
$this->check_exists(settings::FOLDER.'/log_'.$log_marker.'.dat');
while (settings::LOG_SPLIT_SIZE <= filesize(settings::FOLDER.'/log_'.$log_marker.'.dat')) { $log_marker++; $this->check_exists(settings::FOLDER.'/log_'.$log_marker.'.dat'); }
$file = fopen(settings::FOLDER.'/log_'.$log_marker.'.dat', 'ab');
flock($file, LOCK_EX);
fwrite($file, '######################################'."\r\n".'--'.gmdate('Y/m/d H:i')."--\r\n");
fwrite($file, '@@@@@@[ENVIRONMENT VARIABLES]@@@@@@'."\r\n");
foreach ($this->runtime->runtime->env_variables as $key=>$value) {
if ($key !== false && $value !== false) {
fwrite($file, '['.$key.']'.'('.(string)$value.")\r\n");
}
}
fwrite($file, '@@@@@@[GWC VARIABLES]@@@@@@'."\r\n");
foreach ($this->runtime->runtime->gwc_variables as $key=>$value) {
if ($key !== false && $value !== false) {
fwrite($file, '['.$key.']'.'('.(string)$value.")\r\n");
}
}
fwrite($file, '@@@@@@[WARNINGS]@@@@@@'."\r\n");
if (!empty($this->runtime->info['warnings'])) {
foreach ($this->runtime->info['warnings'] as $key=>$value) {
if ($key !== false && $value !== false) {
fwrite($file, '['.$key.']'.'('.(string)$value.")\r\n");
}
}
}
flock($file, LOCK_UN);
fclose($file);
}
protected function compile_saves() {
return ((($this->runtime->ID == 'ip') ? $this->runtime->runtime->final_ip : $this->runtime->runtime->gwc_variables[$this->runtime->ID]).'|'.
time().'|'.
$this->runtime->runtime->gwc_variables['client'].(($this->runtime->runtime->gwc_variables['version'] !== false) ? $this->runtime->runtime->gwc_variables['version'] : '').'|'.
(($this->runtime->ID == 'ip') ? (($this->runtime->runtime->gwc_variables['cluster'] !== false) ? $this->runtime->runtime->gwc_variables['cluster'] : '') : ((isset($this->runtime->runtime->pong)) ? $this->runtime->runtime->pong : '')).'|'.
(($this->runtime->ID == 'ip') ? (($this->runtime->runtime->gwc_variables['x_leaves'] !== false) ? $this->runtime->runtime->gwc_variables['x_leaves'] : '') : ((isset($this->runtime->runtime->host_count)) ? $this->runtime->runtime->host_count : '0')).'|'.
(($this->runtime->ID == 'ip') ? (($this->runtime->runtime->gwc_variables['uptime'] !== false) ? $this->runtime->runtime->gwc_variables['uptime'] : '') : ((isset($this->runtime->runtime->url_count)) ? $this->runtime->runtime->url_count : '0')).'|'.
(($this->runtime->ID == 'ip') ? (($this->runtime->runtime->gwc_variables['x_max'] !== false) ? $this->runtime->runtime->gwc_variables['x_max'] : '') : ((isset($this->runtime->runtime->v1_cache)) ? (int)$this->runtime->runtime->v1_cache : '0')).'|'.
(($this->runtime->ID == 'ip') ? (($this->runtime->runtime->gwc_variables['vendor_only'] !== false) ? $this->runtime->runtime->gwc_variables['vendor_only'] : '') : ((isset($this->runtime->runtime->v2_cache)) ? (int)$this->runtime->runtime->v2_cache : '0')).'|'.
(($this->runtime->ID == 'ip') ? (($this->runtime->runtime->ipv6) ? '6' : '4') : ((strlen($this->runtime->runtime->url_ip)) ? $this->runtime->runtime->url_ip : '')).'|');
}
protected function compile_client_stats() {
return ($this->runtime->runtime->gwc_variables['client'].
(($this->runtime->runtime->gwc_variables['version'] !== false) ? $this->runtime->runtime->gwc_variables['version'] : '').'|'.
(($this->runtime->runtime->gwc_variables['ip'] !== false || $this->runtime->runtime->gwc_variables['ipv6'] !== false) ? '1' : '0').'|'.
(($this->runtime->runtime->gwc_variables['url'] !== false) ? '1' : '0').'|'.
(($this->runtime->runtime->gwc_variables['ping']) ? '1' : '0').'|'.
(($this->runtime->runtime->gwc_variables['get'] || $this->runtime->runtime->gwc_variables['hostfile'] || $this->runtime->runtime->gwc_variables['urlfile']) ? '1' : '0').'|'.
(($this->runtime->runtime->gwc_variables['info'] || $this->runtime->runtime->gwc_variables['support'] || $this->runtime->runtime->gwc_variables['statfile']) ? '1' : '0'));
}
protected function compile_retries($host, $bad_count=0) {
return ($host.'|'.time().'|'.'Self-Add'.'|'.((string)$bad_count).'|');
}
protected function filter_bad($data) {
$hosts = array();
$filtered = array(
'good'=>array(),
'bad'=>array(),
'expired'=>array()
);
if (!empty($data)) {
while (count($data) > $this->maximum) {
$filtered['bad'][] = array_shift($data);
}
foreach ($data as $line) {
$host = $timestamp = '';
list($host, $timestamp) = explode('|', $line);
if (strlen($host) === 0 || strlen($timestamp) === 0 || in_array($host, $hosts)) {
$filtered['bad'][] = $line;
}
elseif ((time() - (int)$timestamp) >= ($this->expire * 3600)) {
$filtered['bad'][] = $line;
$filtered['expired'][] = $host;
}
else {
$filtered['good'][] = $line;
}
$hosts[] = $host;
}
}
if (!empty($filtered['good'])) {
$filtered['good'] = array_unique($filtered['good']);
}
if (!empty($filtered['bad'])) {
$this->remove_bad(array_unique($filtered['bad']));
}
if (!empty($filtered['expired']) && (($this->runtime->ID == 'url' && settings::RETRY_URLS) or ($this->runtime->ID == 'bad_url' && settings::RETRY_BAD_URLS))) {
$this->add_retry(array_unique($filtered['expired']));
}
return $filtered['good'];
}
protected function all_requests($shuffle, $number_out) {
$contents = $this->contents = array_reverse($this->filter_bad($this->grab()));
if (!empty($contents)) {
($shuffle) ? shuffle($contents) : $contents = $contents;
foreach ($contents as $key=>$value) {
if (!$this->runtime->runtime->gwc_variables['getv6'] && $this->runtime->ID == 'ip') { //Filter out IPv6 addresses when not requested...
if ($value[0] == '[') {
unset($contents[$key]);
}
}
}
if (count($contents) > $number_out) {
while (count($contents) > $number_out) {
array_shift($contents);
}
}
}
$this->output = $contents;
}
protected abstract function grab();
protected abstract function update_stats();
protected abstract function add_retry($retries);
protected abstract function remove_bad($bad_lines);
protected abstract function add();
protected abstract function url_retry();
}
class files extends data_system {
function __construct($runtime) {
parent::__construct($runtime);
}
protected function file($handle) {
$data = array();
while(!feof($handle)) {
if ($data_found = fgets($handle)) {
if (strlen($data_found) >= 1) {
$data_found = trim($data_found);
if (strlen($data_found) >= 1) {
$data[] = $data_found;
}
}
}
}
@rewind($handle); //We have to rewind, as there's a file-system bug in Unix that places a NULL character on data append for next operation.
return $data;
}
protected function grab() {
$file = @fopen($this->file, 'rb');
$this->file_handle_check($file);
flock($file, LOCK_SH);
$contents = $this->file($file);
flock($file, LOCK_UN);
fclose($file);
return $contents;
}
protected function file_handle_check($file) {
if ($file === false) { throw new Exception('Failed to open file '.$this->file); }
}
protected function update_stats() {
$file = @fopen($this->file, 'r+b');
$this->file_handle_check($file);
flock($file, LOCK_EX);
if ($this->runtime->ID == 'stats_total_requests' || $this->runtime->ID == 'stats_total_updates') {
$data = $this->file($file);
ftruncate($file, 0);
fwrite($file, (!empty($data) ? ($data[0] + 1) : '1'));
}
elseif ($this->runtime->ID == 'stats_client') {
$data = $this->file($file); $data2 = '';
if (!empty($data) && count($data) >= settings::STATS_THROTTLE) {
ftruncate($file, 0);
while (count($data) >= settings::STATS_THROTTLE) {
array_shift($data);
}
fwrite($file, implode("\r\n", $data)."\r\n".$this->compile_client_stats()."\r\n");
}
else {
fseek($file, 0, SEEK_END);
fwrite($file, $this->compile_client_stats()."\r\n");
}
}
elseif ($this->runtime->ID == 'stats_requests' || $this->runtime->ID == 'stats_updates') {
$outdated = false;
$data = $this->file($file); $data2 = '';
if (!empty($data)) {
foreach ($data as $time) {
if ((time() - ((int)$time)) < 3600) {
$data2 .= $time."\r\n";
}
else {
$outdated = true;
}
}
if ($outdated) {
ftruncate($file, 0);
if (!empty($data2)) {
fwrite($file, $data2);
}
}
}
if (!$this->refresh) {
if (!$outdated) {
fseek($file, 0, SEEK_END);
}
fwrite($file, time()."\r\n");
}
}
flock($file, LOCK_UN);
fclose($file);
}
protected function add_retry($retries) {
$file = @fopen(settings::FOLDER.'/retry'.$this->runtime->network.'.dat', 'ab');
$this->file_handle_check($file);
flock($file, LOCK_EX);
foreach ($retries as $host) {
fwrite($file, $this->compile_retries($host)."\r\n");
}
flock($file, LOCK_UN);
fclose($file);
}
protected function remove_bad($bad_lines) {
$file = @fopen($this->file, 'r+b');
$this->file_handle_check($file);
flock($file, LOCK_EX);
$data = $this->file($file);
ftruncate($file, 0);
foreach ($data as $line) {
if (!in_array($line, $bad_lines)) {
fwrite($file, $line."\r\n");
}
}
flock($file, LOCK_UN);
fclose($file);
}
protected function add() {
$file = @fopen($this->file, 'ab');
$this->file_handle_check($file);
flock($file, LOCK_EX);
fwrite($file, $this->compile_saves()."\r\n");
flock($file, LOCK_UN);
fclose($file);
}
protected function url_retry() {
$file = @fopen($this->file, 'r+b');
$this->file_handle_check($file);
flock($file, LOCK_EX);
$this->contents = $this->file($file);
if (!empty($this->contents)) {
$urls_to_retry = '';
if (count($this->contents) > 1) {
array_shift($this->contents);
$urls_to_retry = implode("\r\n", $this->contents);
}
ftruncate($file, 0);
fwrite($file, $urls_to_retry);
}
flock($file, LOCK_UN);
fclose($file);
}
}
abstract class mysql_routine_control extends data_system {
protected static $connection = false;
function __construct($runtime) {
//Linking contructor call of lower classes with the data_system constructor:
parent::__construct($runtime);
}
protected function grab() {
$link = $this->query('SELECT data FROM '.$this->clean($this->name).' ORDER BY id;');
$contents = array();
if (!$this->error($link)) {
while($row_returned = $this->mysql_fetch_row($link)) {
$contents[] = $row_returned[0];
}
}
return ((!empty($contents)) ? array_map('trim', $contents) : $contents);
}
protected function update_stats() {
if ($this->runtime->ID == 'stats_total_requests' || $this->runtime->ID == 'stats_total_updates') {
$data = array();
$link = $this->query('SELECT data FROM '.$this->clean($this->name).' ORDER BY id;');
if (!$this->error($link)) {
while($row_returned = $this->mysql_fetch_row($link)) {
$data[] = $row_returned[0];
}
}
if (empty($data)) {
$this->query('INSERT INTO '.$this->clean($this->name).'( data ) VALUES( \'1\' );');
}
else {
$this->query('UPDATE '.$this->clean($this->name).' SET data = \''.($data[0] + 1).'\';');
}
}
elseif ($this->runtime->ID == 'stats_client') {
$link = $this->query('SELECT COUNT(data) as num_clients FROM '.$this->clean($this->name).' ORDER BY id;');
if (!$this->error($link)) {
$count = 0;
if ($row_returned = $this->mysql_fetch_row($link)) {
$count = (int)$row_returned[0];
}
if ($count > 0) {
if ($count > (settings::STATS_THROTTLE * ((int)settings::STATS_CLIENT_FLUSH))) {
$this->query('TRUNCATE TABLE '.$this->clean($this->name).';');
}
}
}
$this->query('INSERT INTO '.$this->clean($this->name).'( data ) VALUES( \''.$this->clean($this->compile_client_stats()).'\' );');
}
elseif ($this->runtime->ID == 'stats_requests' || $this->runtime->ID == 'stats_updates') {
$this->query('DELETE FROM '.$this->clean($this->name).' WHERE data < '.(time() - 3600).';');
if (!$this->refresh) { $this->query('INSERT INTO '.$this->clean($this->name).'( data ) VALUES( \''.time().'\' );'); }
}
}
protected function add_retry($retries) {
foreach ($retries as $host) {
$this->query('INSERT INTO retry'.$this->runtime->network.'( data ) VALUES( \''.$this->compile_retries($host).'\' );');
}
}
protected function remove_bad($bad_lines) {
$lines = array();
foreach ($bad_lines as $line) {
$lines[] = 'data = \''.$this->clean($line).'\'';
}
$this->query('DELETE FROM '.$this->clean($this->name).' WHERE '.implode(' OR ', $lines).';');
}
protected function add() {
$this->query('INSERT INTO '.$this->clean($this->name).'( data ) VALUES( \''.$this->clean($this->compile_saves()).'\' );');
}
protected function url_retry() {
$link = $this->query('SELECT data, id FROM '.$this->clean($this->name).' ORDER BY id;');
if (!$this->error($link)) {
if ($row_returned = $this->mysql_fetch_row($link)) {
$this->contents[0] = $row_returned[0];
$id = $row_returned[1];
}
if (isset($id)) {
$this->query('DELETE FROM '.$this->clean($this->name).' WHERE id = \''.$this->clean($id).'\';');
}
}
}
///Below are the functions not executed by class data_system, but used instead by the child mysql handler classes:
protected function generate_table() {
return $this->direct_query('CREATE TABLE '.$this->clean($this->name).' ( id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY( id ), data TEXT( 500 ) );');
}
protected function query($query) {
$result = $this->direct_query($query);
if ($this->error($result)) {
$error_message = $this->obtain_error();
if (!$this->error($this->generate_table())) {
$result = $this->direct_query($query);
}
else {
throw new Exception('MySQL: '.$error_message);
}
}
return $result;
}
public abstract function clean($data);
public abstract function mysql_fetch_row($link);
public abstract function direct_query($query);
public abstract function error($link);
public abstract function obtain_error();
}
class mysql extends mysql_routine_control {
public $fallback;
function __construct($runtime) {
if (self::$connection !== false) {
parent::__construct($runtime);
}
else if ((self::$connection = @mysql_pconnect(settings::DBA_ADDRESS, settings::DBA_USERNAME, settings::DBA_PASSWORD)) === false) {
$this->fallback = true;
}
else {
if (@mysql_select_db(settings::DBA_NAME, self::$connection) !== false) {
parent::__construct($runtime);
}
else {
$this->fallback = true;
}
}
}
///Functions are public, as they are used by the class mysql_routine_control:
public function clean($data) {
return mysql_real_escape_string($data);
}
public function mysql_fetch_row($link) {
return mysql_fetch_row($link);
}
public function direct_query($query) {
return mysql_query($query, self::$connection);
}
public function error($link) {
return (($link === false) ? true : false);
}
public function obtain_error() {
return mysql_error();
}
}
class mysql_adv extends mysql_routine_control {
public $fallback;
function __construct($runtime) {
//Persistent connections are ignored in mysqli still, so static connection variable should return false.
self::$connection = (self::$connection) ? self::$connection : new mysqli(settings::DBA_ADDRESS, settings::DBA_USERNAME, settings::DBA_PASSWORD, settings::DBA_NAME);
(self::$connection->error || !self::$connection) ? $this->fallback = true : parent::__construct($runtime);
}
///Functions are public, as they are used by the class mysql_routine_control:
public function clean($data) {
return self::$connection->real_escape_string($data);
}
public function mysql_fetch_row($result) {
return $result->fetch_row();
}
public function direct_query($query) {
return self::$connection->query($query);
}
public function error($result) {
return ((self::$connection->error !== '' || $result === false) ? true : false);
}
public function obtain_error() {
return self::$connection->error;
}
function __destruct() {
//Connection in mysqli NOT persistent, so must close.
self::$connection->close();
}
}
class data_manage {
public $data;
public $flow;
public $ID;
public $runtime;
public $info;
function __construct($runtime, $flow, $ID, $network='', $info=array()) {
$this->ID = $ID;
$this->flow = $flow;
$this->network = strtolower((strlen($network) >= 1) ? '_'.$network : '');
$this->runtime = $runtime;
$this->info = $info;
$this->decide();
}
public function decide() {
switch (strtolower(settings::STORAGE)) {
case 'mysql':
$this->data = new mysql($this);
break;
case 'mysqli':
$this->data = new mysql_adv($this);
break;
case 'flat':
$this->data = new files($this);
break;
default:
throw new Exception('Improper configuration/Invalid STORAGE value ( \''.settings::STORAGE.'\' )');
}
$this->data = (isset($this->data->fallback)) ? new files($this) : $this->data;
}
}
class statistics {
public $runtime;
public $type;
public $network;
function __construct($runtime, $type, $network='') {
$this->runtime = $runtime;
$this->type = $type;
$this->network = (string)$network;
}
public function output() {
if (settings::ENABLE_HIT_STATS) {
$stats_get = new data_manage($this->runtime, 'down', 'stats_total_requests', $this->network);
(!empty($stats_get->data->contents)) ? $stats[0] = $stats_get->data->contents[0] : $stats[0] = 0;
$stats_get = new data_manage($this->runtime, 'down', 'stats_total_updates', $this->network);
(!empty($stats_get->data->contents)) ? $stats[0] += $stats_get->data->contents[0] : $stats[0] = $stats[0];
$stats_get = new data_manage($this->runtime, 'down', 'stats_requests', $this->network);
(!empty($stats_get->data->contents)) ? $stats[1] = count($stats_get->data->contents) : $stats[1] = '0';
$stats_get = new data_manage($this->runtime, 'down', 'stats_updates', $this->network);
(!empty($stats_get->data->contents)) ? $stats[2] = count($stats_get->data->contents) : $stats[2] = '0';
$stat = implode("\r\n", $stats);
return $stat."\r\n";
}
else {
return '0'."\r\n".'0'."\r\n".'0'."\r\n";
}
}
public function update() {
if ($this->type == 'request' && settings::ENABLE_HIT_STATS) {
$stats_up = new data_manage($this->runtime, 'up', 'stats_total_requests', $this->network);
$stats_up = new data_manage($this->runtime, 'up', 'stats_requests', $this->network);
}
elseif ($this->type == 'update' && settings::ENABLE_HIT_STATS) {
$stats_up = new data_manage($this->runtime, 'up', 'stats_total_updates', $this->network);
$stats_up = new data_manage($this->runtime, 'up', 'stats_updates', $this->network);
}
elseif ($this->type == 'client' && settings::WEB_FRONT && settings::ENABLE_CLIENT_STATS) {
$stats_up = new data_manage($this->runtime, 'up', 'stats_client', $this->network);
}
}
}
class client_check {
public $runtime;
function __construct($runtime) {
$this->runtime = $runtime;
}
public function bans($warns=array()) {
$warnings = array();
if (!empty($this->runtime->settings->BANNED)) {
foreach ($this->runtime->settings->BANNED as $bad_ip) {
if ($bad_ip == substr($this->runtime->env_variables['client_ip'], 0, strlen($bad_ip))) {
$warnings[] = 'Banned IP Address';
break;
}
}
}
if (!empty($this->runtime->settings->VENDOR_CODE_BAN) && $this->runtime->gwc_variables['client'] !== false) {
$client_modified = ($this->runtime->gwc_variables['version'] !== false) ? $this->runtime->gwc_variables['client'].$this->runtime->gwc_variables['version'] : $this->runtime->gwc_variables['client'];
foreach ($this->runtime->settings->VENDOR_CODE_BAN as $bad_vendor) {
if (stripos($client_modified, $bad_vendor) === 0) {
$warnings[] = 'Banned Vendor Code';
break;
}
}
}
if ($this->runtime->gwc_variables['ip'] !== false || $this->runtime->gwc_variables['ipv6'] !== false) {
if (!empty($this->runtime->settings->VENDOR_CODE_IP_UPDATE_BAN) && $this->runtime->gwc_variables['client'] !== false) {
$client_vendor_update = ($this->runtime->gwc_variables['version'] !== false) ? $this->runtime->gwc_variables['client'].$this->runtime->gwc_variables['version'] : $this->runtime->gwc_variables['client'];
foreach ($this->runtime->settings->VENDOR_CODE_IP_UPDATE_BAN as $bad_update_vendor) {
if (stripos($client_vendor_update, $bad_update_vendor) === 0) {
$warnings[] = 'Vendor Code banned from updating an IP address';
}
}
}
if ($this->runtime->gwc_variables['cache']) {
$warnings[] = 'IP updates from web caches not allowed';
}
}
if ($this->runtime->env_variables['user_agent']) {
if (!empty($this->runtime->settings->USER_AGENT_BAN)) {
foreach ($this->runtime->settings->USER_AGENT_BAN as $bad_user_agent) {
if (stripos($this->runtime->env_variables['user_agent'], $bad_user_agent) !== false) {
$warnings[] = 'Banned User Agent';
break;
}
}
}
if (!empty($this->runtime->settings->WHITELIST_USER_AGENT)) {
$network_found = $whitelisted = false;
foreach ($this->runtime->settings->WHITELIST_USER_AGENT as $good_user_agent=>$network) {
if ($network == $this->runtime->gwc_variables['net']) {
$network_found = true;
if (stripos($this->runtime->env_variables['user_agent'], $good_user_agent) === 0) {
$whitelisted = true;
break;
}
}
}
if (!$whitelisted && $network_found) {
$warnings[] = 'Banned by user agent whitelist';
}
}
if ($this->runtime->env_variables['user_agent'] != 'Mozilla/4.0') {
if (!empty($this->runtime->settings->BROWSER_DETECT) && ($this->runtime->gwc_variables['ip'] !== false || $this->runtime->gwc_variables['ipv6'] !== false)) {
foreach ($this->runtime->settings->BROWSER_DETECT as $browser_user_agent) {
if (stripos($this->runtime->env_variables['user_agent'], $browser_user_agent) !== false) {
$warnings[] = 'Browser banned from updating an IP address';
break;
}
}
}
}
else {
if ($this->runtime->gwc_variables['client'] !== false && !empty($this->runtime->settings->BAN_GDNA_CLONES)) {
foreach ($this->runtime->settings->BAN_GDNA_CLONES as $banned_gdna_clone) {
if (stripos($this->runtime->gwc_variables['client'], $banned_gdna_clone) !== false) {
$warnings[] = 'GnucDNA clone banned from the cache';
break;
}
}
}
}
}
else {
if (($this->runtime->gwc_variables['ip'] !== false || $this->runtime->gwc_variables['ipv6'] !== false) && settings::BLOCK_NO_USER_AGENT) {
$warnings[] = 'Clients with no user-agent banned from updating IP addresses';
}
elseif (settings::BLOCK_NO_USER_AGENT_ALL) {
$warnings[] = 'Clients with no user-agent banned';
}
}
if (!empty($warnings)) {
header('HTTP/1.1 404 Not Found');
if ($warnings && settings::LOG_BAN_WARNINGS) {
$log = new data_manage($this->runtime, 'up', 'log', '', array('warnings'=>$warnings));
}
}
return array_merge($warnings, $warns);
}
}
class update {
public $info;
public $success;
public $warnings;
private $already_submitted;
private $url_port;
private $domain;
private $folder;
private $unsafe_folder;
private $domain_without_port;
private $ip_v1_found_in_cache;
private $ip_v2_found_in_cache;
private $url_v1_found_in_cache;
private $url_v2_found_in_cache;
private $v2_h_block_found;
private $v2_u_block_found;
private $v2_i_block_found;
private $response_data;
function __construct($info, $type, $network='') {
$this->info = $info;
$this->info->ip = '';
$this->info->final_ip = '';
$this->info->ipv6 = false;
$this->info->url_ip = '';
$this->success = false;
$this->warnings = array();
$this->info->host_count = 0;
$this->info->url_count = 0;
$this->info->pong = '';
$this->info->v1_cache = false;
$this->info->v2_cache = false;
$this->already_submitted = false;
$this->url_port = 80;
$this->ip_v1_found_in_cache = false;
$this->ip_v2_found_in_cache = false;
$this->url_v1_found_in_cache = false;
$this->url_v2_found_in_cache = false;
$this->v2_h_block_found = false;
$this->v2_u_block_found = false;
$this->v2_i_block_found = false;
$this->network = (string)$network;
switch ($type) {
case 'ip':
$this->ip_validate();
break;
case 'url':
$this->url_validate();
break;
case 'retry':
$this->url_retry();
}
if (!empty($this->warnings)) {
$this->logging();
}
}
private function save($type) {
switch ($type) {
case 'ip':
case 'ipv6':
case 'bad_url':
case 'url':
$upline = new data_manage($this->info, 'up', $type, $this->network);
break;
default:
throw new Exception('Bad ID ( \''.$type.'\' )');
}
}
private function logging() {
if (settings::LOG_UPDATE_WARNINGS) {
$this->log = new data_manage($this->info, 'up', 'log', '', array('warnings'=>$this->warnings));
}
}
private function url_retry() {
if (settings::RETRY_URLS) {
$grab = new data_manage($this->info, 'down', 'retry', $this->network);
if (isset($grab->data->contents)) {
if (!empty($grab->data->contents)) {
if (strlen($grab->data->contents[0]) > 10) {
$client_temp = $this->info->gwc_variables['client'].((strlen($this->info->gwc_variables['version']) >= 1) ? $this->info->gwc_variables['version'] : ''); $this->info->gwc_variables['version'] = '';
list($this->info->gwc_variables['url'],,$this->info->gwc_variables['client']) = explode('|', $grab->data->contents[0]);
$this->url_validate();
$this->info->gwc_variables['client'] = $client_temp;
}
}
}
}
}
private function ipv6_check($ip) {
if (strlen($ip) > 18) {
if ((($units = substr_count($ip, ':')) > 2) && $ip[0] == '[' && substr_count($ip, ']') == 1) {
$this->info->ip = substr(strtolower($ip), 1, strpos($ip, ']') - 1); //I like lower-case hexidecimal digits...
$this->info->port = substr($ip, strrpos($ip, ':') + 1);
$ipv6 = explode(':', $this->info->ip);
if (count($ipv6) == $units) {
$zero_skip = false;
foreach ($ipv6 as $ipv6_segment) {
if (strlen($ipv6_segment) <= 4) {
if (strlen($ipv6_segment) >= 1) {
if (ereg('[^[:xdigit:]]', $ipv6_segment)) {
$this->warnings[] = 'IP is not hexadecimal';
break;
}
}
else {
if ($zero_skip || $units == 8) {
$this->warnings[] = 'IP contains illegal format';
}
$zero_skip = true;
}
}
else {
$this->warnings[] = 'IP numerical segment too large';
break;
}
}
$this->port_check();
}
else {
$this->warnings[] = 'IP segment count wrong';
}
}
else {
$this->warnings[] = 'IP contains illegal format';
}
}
else {
$this->warnings[] = 'IP too short';
}
return (empty($this->warnings)) ? true : false;
}
private function ipv4_check($ip) {
if (strlen($ip) > 8) {
if (substr_count($ip, ':') === 1) {
list($this->info->ip, $this->info->port) = explode(':', $ip);
$ipv4 = explode('.', $this->info->ip);
if (count($ipv4) == 4) {
foreach ($ipv4 as $ipv4_segment) {
if (strlen($ipv4_segment) >= 1 && strlen($ipv4_segment) <= 3) {
if (ctype_digit($ipv4_segment)) {
if ($ipv4_segment > 255) {
$this->warnings[] = 'IP numerical segment out-of-bounds';
break;
}
}
else {
$this->warnings[] = 'IP numerical segment contains illegal format';
break;
}
}
else {
$this->warnings[] = 'IP numerical segment too large';
break;
}
}
$this->port_check();
}
else {
$this->warnings[] = 'IP segment count wrong';
}
}
else {
$this->warnings[] = 'IP contains illegal format';
}
}
else {
$this->warnings[] = 'IP too short';
}
return (empty($this->warnings)) ? true : false;
}
private function port_check() {
if (empty($this->warnings)) {
if (strlen($this->info->port) >= 1 && strlen($this->info->port) <= 5) {
if (ctype_digit($this->info->port)) {
if ($this->info->port < 1 || $this->info->port > 65535) {
$this->warnings[] = 'Port number out of bounds';
}
}
else {
$this->warnings[] = 'Port number contains illegal characters';
}
}
else {
$this->warnings[] = 'Illegal length of the port number';
}
}
}
private function ip_validate() {
if (settings::EXPIRE_HOSTS > 0) {
if ($this->info->gwc_variables['ip'] !== false && $this->ipv4_check($this->info->env_variables['client_ip'].':1')) {
$this->success = $this->ipv4_check($this->info->gwc_variables['ip']);
}
elseif ($this->info->gwc_variables['ipv6'] !== false && $this->ipv6_check('['.$this->info->env_variables['client_ip'].']:1')) {
$this->info->ipv6 = true;
$this->success = $this->ipv6_check($this->info->gwc_variables['ipv6']);
}
else {
throw new Exception('IP version incompatible');
}
if ($this->success) {
if (inet_pton($this->info->env_variables['client_ip']) !== inet_pton($this->info->ip)) {
$this->success = false;
$this->warnings[] = 'IP is not self';
}
}
if ($this->success) {
//Check to see if overwriting of given IP is needed...
if (!empty($this->info->settings->IP_EXCEPTION)) {
if (in_array($this->network, $this->info->settings->IP_EXCEPTION)) {
$this->info->ip = $this->info->env_variables['client_ip'];
}
}
//Merge IP back into one...
$this->info->final_ip = (($this->info->ipv6) ? '['.$this->info->ip.']' : $this->info->ip).':'.$this->info->port;
//Check if already in cache...
$grab = new data_manage($this->info, 'down', 'ip', $this->network);
if (isset($grab->data->contents)) {
if (!empty($grab->data->contents)) {
foreach ($grab->data->contents as $listing) {
list($ip_selected,,,,,,,,$ip_type) = explode('|', $listing);
$ip_selected_no_port = ($ip_type != 6) ? substr($ip_selected, 0, strpos($ip_selected, ':')) : substr($ip_selected, 1, strrpos($ip_selected, ']') - 1);
if (inet_pton($this->info->ip) === inet_pton($ip_selected_no_port)) {
$this->success = false;
$this->warnings[] = 'Already Submitted';
break;
}
}
}
}
($this->success) ? $this->save('ip') : $this->success = true;
}
}
else {
throw new Exception('Cache settings error'); //Give ERROR, as this setting is critical.
}
}
private function url_validate() {
if (strlen($this->info->gwc_variables['url']) > 10) {
if (strlen($this->info->gwc_variables['url']) < 256) {
if (strpos($this->info->gwc_variables['url'], 'http://') === 0) {
if (stripos($this->info->gwc_variables['url'], 'nyud.net') === false && stripos($this->info->gwc_variables['url'], 'nyucd.net') === false) {
$url_without_http = substr($this->info->gwc_variables['url'], 7);
$first_dot = strpos($url_without_http, '.');
$first_slash = strpos($url_without_http, '/');
if ($first_dot !== false && $first_slash !== false) {
if ($first_slash > 3) {
if ($first_dot < $first_slash) {
if (strpos($url_without_http, './') === false && strpos($url_without_http, '//') === false && strpos($url_without_http, '/.') === false) {
$last_slash = strrpos($url_without_http, '/');
$last_q_mark = strrpos($url_without_http, '?');
if ($last_q_mark === false || $last_slash > $last_q_mark) {
$this->test_gwc($url_without_http);
}
else {
$this->warnings[] = 'No query string in the URL allowed';
}
}
else {
$this->warnings[] = 'Illegal format';
}
}
else {
$this->warnings[] = 'Impossible URL';
}
}
else {
$this->warnings[] = 'Domain is too short';
}
}
else {
$this->warnings[] = 'Missing needed URL character';
}
}
else {
$this->warnings[] = 'nyud.net not allowed';
}
}
else {
$this->warnings[] = 'HTTP only';
}
}
else {
$this->warnings[] = 'URL too long';
}
}
else {
$this->warnings[] = 'URL too short';
}
}
private function domain_compute($url) {
$domain_length = strpos($url, '/');
$this->domain = strtolower(substr($url, 0, $domain_length));
$this->unsafe_folder = substr($url, $domain_length);
$this->folder = $this->info->convert_out_of_set_chars($this->unsafe_folder); //To encode out-of-set chars...
$this->info->gwc_variables['url'] = 'http://'.$this->domain.$this->unsafe_folder;
}
private function compare_domains($url) {
$domain_url = substr($url, 0, strpos($url, '/'));
if ($port_begin = strpos($domain_url, ':')) {
$domain_url = substr($domain_url, 0, $port_begin);
}
return ((strtolower($domain_url) == $this->domain_without_port) ? true : false);
}
private function port_obtain() {
if ($port_begin = strpos($this->domain, ':')) {
$this->url_port = substr($this->domain, ($port_begin + 1));
$this->domain_without_port = substr($this->domain, 0, $port_begin);
if (strlen($this->url_port) === 0) {
//This check added for PHP 5.0.X returning true on an empty string to ctype_digit().
$this->warnings[] = 'Port number is zero-length';
}
elseif (!ctype_digit($this->url_port)) {
$this->warnings[] = 'Port number contains illegal characters';
}
elseif (((int)$this->url_port) == 80) {
$this->info->gwc_variables['url'] = 'http://'.$this->domain_without_port.$this->unsafe_folder;
}
if ($this->url_port != 80 && !settings::NON_HTTP && settings::FSOCKOPEN && function_exists('fsockopen')) {
$this->warnings[] = 'Port of URL is out of reach for this cache';
}
$this->url_port = (int)$this->url_port;
}
else {
$this->domain_without_port = $this->domain;
}
}
private function compare_pong($pong) {
if (strlen($pong) >= 1) {
if (strlen($pong) > 100) { $pong = substr($pong, 0, 100); }
if (!empty($this->info->settings->BANNED_PONGS)) {
foreach ($this->info->settings->BANNED_PONGS as $bad_pong) {
if (strtolower($bad_pong) == strtolower(substr($pong, 0, strlen($bad_pong))) && strlen($bad_pong) >= 1) {
$this->warnings[] = 'Banned PONG response found';
break;
}
}
}
}
return $pong;
}
private function test_prechecks() {
if (empty($this->warnings)) {
if (!empty($this->info->settings->BANNED_URLS)) {
if (in_array($this->info->gwc_variables['url'], $this->info->settings->BANNED_URLS)) {
$this->warnings[] = 'Permanently banned URL';
}
}
}
if (ip2long($this->domain_without_port) && !settings::IP_ALT_CACHES) {
$this->warnings[] = 'IP addresses not accepted';
}
if (empty($this->warnings)) {
$grab = new data_manage($this->info, 'down', 'bad_url', $this->network);
if (isset($grab->data->contents)) {
if (!empty($grab->data->contents)) {
foreach ($grab->data->contents as $listing) {
list($bracketless_url) = explode('|', $listing);
if (strtolower($this->info->gwc_variables['url']) == strtolower($bracketless_url)) {
$this->warnings[] = 'Temporarily banned URL';
$this->success = false;
break;
}
}
}
}
}
if (empty($this->warnings)) {
$this->info->url_ip = gethostbyname($this->domain_without_port);
$grab = new data_manage($this->info, 'down', 'url', $this->network);
if (isset($grab->data->contents)) {
if (!empty($grab->data->contents)) {
foreach ($grab->data->contents as $listing) {
list($bracketless_url,,,,,,,,$server_ip) = explode('|', $listing);
if ($this->compare_domains(substr($bracketless_url, 7)) || $this->info->url_ip == $server_ip) {
$this->already_submitted = true;
$this->warnings[] = 'Already Submitted';
$this->success = true;
break;
}
}
}
}
}
}
private function obtain_socket_out($query='', $read_stream=true) {
$this->response_data = array();
$begin_time = time();
$socket = @fsockopen($this->domain, $this->url_port, $errno, $errstr, settings::TIMEOUT);
if ($socket) {
$writing = 'GET '.$this->folder.$query.' HTTP/1.0'."\r\n";
$writing .= 'Host: '.$this->domain."\r\n";
$writing .= 'User-Agent: '.settings::CACHE_NAME.' '.settings::CACHE_VERSION.' ('.settings::CACHE_VENDOR.')'."\r\n";
$writing .= 'Connection: Close'."\r\n\r\n";
fwrite($socket, $writing);
stream_set_blocking($socket, 0);
stream_set_timeout($socket, settings::TIMEOUT - time() + $begin_time);
if ($read_stream) {
return $this->obtain_and_sort($socket);
}
fclose($socket);
return true;
}
return false;
}
private function check_for_timeout($socket) {
$info = stream_get_meta_data($socket);
return $info['timed_out'];
}
private function obtain_and_sort($socket) {
$data = '';
while (!feof($socket) && !$this->check_for_timeout($socket)) {
if (false !== ($incoming = fgetc($socket))) {
$data .= $incoming;
}
}
fclose($socket);
if (!empty($data)) {
if (false !== ($offset = strpos($data, "\r\n\r\n"))) {
$data = substr($data, $offset + 4);
$this->response_data = explode("\n", $data);
$this->response_data = array_map('rtrim', $this->response_data);
return true;
}
}
return false;
}
private function test_gwc($url) {
if ($this->info->env_variables['url'] != $url && $this->info->env_variables['url'] != $this->info->convert_out_of_set_chars($url)) {
$this->domain_compute($url);
$this->port_obtain();
if (empty($this->warnings) && settings::EXPIRE_URLS > 0) {
$this->test_prechecks();
if (empty($this->warnings) && !$this->already_submitted) {
if (settings::FSOCKOPEN && function_exists('fsockopen')) {
$query_base = '?client=TEST&version='.$this->info->convert_out_of_set_chars(settings::CACHE_VENDOR.' '.settings::CACHE_VERSION).'&getnetworks=1&cache=1';
$query_net = '&net='.urlencode($this->network);
$query_ping = '&ping=1';
$query_get = '&get=1&hostfile=1';
$query_update_url = '&update=1&url='.urlencode('http://'.$this->info->env_variables['url']);
$mute_cache = false;
if ($this->obtain_socket_out($query_base.$query_net.$query_ping)) {
foreach ($this->response_data as $line) {
if (!empty($this->warnings)) { break; }
if (empty($line)) { continue; }
$v2_break_feed = explode('|', strtolower($line));
$v2_break_feed_i = explode('|', $line);
if (count($v2_break_feed) >= 2) {
$this->info->v2_cache = true;
switch ($v2_break_feed[0]) {
case 'i':
$this->v2_i_block_found = true;
switch ($v2_break_feed[1]) {
case 'error':
$this->warnings[] = 'Query Error';
break;
case 'net-not-supported':
$this->warnings[] = 'Network not supported';
break;
case 'pong':
if (count($v2_break_feed) >= 3) {
$this->info->pong = $this->compare_pong($this->info->strip_chars($v2_break_feed_i[2]));
if (count($v2_break_feed) >= 4) {
$networks_supported = explode('-', $v2_break_feed[3]);
foreach ($networks_supported as $network_supported) {
if ($this->network == strtolower($network_supported)) { break 2; }
}
$this->warnings[] = 'Network not supported';
}
}
else {
$this->warnings[] = 'Pong is incomplete';
}
break;
case 'networks':
if (count($v2_break_feed) >= 3) {
$index = 2;
while (isset($v2_break_feed[$index])) {
if ($this->network == strtolower($v2_break_feed[$index])) { break 2; }
$index++;
}
$this->warnings[] = 'Network not supported';
}
else {
$this->warnings[] = 'Incomplete informational tag';
}
break;
case 'nets':
if (count($v2_break_feed) >= 3) {
$networks_supported = explode('-', $v2_break_feed[2]);
foreach ($networks_supported as $network_supported) {
if ($this->network == strtolower($network_supported)) { break 2; }
}
$this->warnings[] = 'Network not supported';
}
else {
$this->warnings[] = 'Incomplete informational tag';
}
}
break;
case 'u':
case 'h':
$this->warnings[] = 'Non-requested data found';
break;
case '<': //Easy way to detect an HTML doc.
$this->warnings[] = 'HTML-like format detected';
}
}
else {
switch ($v2_break_feed[0]) {
case 'u':
case 'h':
case 'i':
case 'd': //Used by jon atkin's cache... (debug)
case 'ukhl': //Reserved
case 'uhc': //Reserved
$this->info->v2_cache = true;
$this->warnings[] = 'Incomplete data tag found';
break;
default:
$this->info->v1_cache = true;
}
if (stripos($line, '<') !== false) {
$this->warnings[] = 'HTML-like format detected';
}
elseif (stripos($line, 'ERROR: Network not supported') === 0) {
$this->warnings[] = 'Network not supported';
}
elseif (stripos($line, 'ERROR') !== false) {
$this->warnings[] = 'Ping Error';
}
elseif (strpos($line, 'PONG') === 0) {
if (strpos($line, 'PONG MWebCache') === 0) {
if ($this->network != 'mute') {
$this->warnings[] = 'Bugged Mute-Net cache detected';
}
elseif (strpos($line, 'PONG MWebCache 0.1.1') === 0) {
$this->warnings[] = 'Bugged Mute-Net cache(vs. 0.1.1) detected';
}
else {
$mute_cache = true;
}
}
$this->info->pong = $this->compare_pong($this->info->strip_chars(substr($line, 5)));
}
elseif (stripos($line, 'WARNING') === 0) {
$this->warnings[] = 'Warning message found';
}
else {
$this->warnings[] = 'Invalid data';
}
}
}
if ($this->info->pong === '' && empty($this->warnings)) {
$this->warnings[] = 'No PONG found';
}
elseif (empty($this->warnings)) {
if ($this->obtain_socket_out($query_base.$query_net.$query_get)) {
foreach ($this->response_data as $line) {
if (!empty($this->warnings)) { break; }
if (empty($line)) { continue; }
$v2_break_feed = explode('|', strtolower($line));
if (count($v2_break_feed) >= 2) {
$this->info->v2_cache = true;
switch ($v2_break_feed[0]) {
case 'u':
$this->v2_u_block_found = true;
if (stripos($v2_break_feed[1], 'http://') === 0) {
$this->url_v2_found_in_cache = true;
$this->info->url_count++;
}
break;
case 'h':
$this->v2_h_block_found = true;
if (!empty($v2_break_feed[1]) && strpos($v2_break_feed[1], ':') !== false) {
if ($this->ipv4_check($v2_break_feed[1]) || $this->ipv6_check($v2_break_feed[1])) {
$this->ip_v2_found_in_cache = true;
$this->info->host_count++;
}
else {
$this->warnings[] = 'Invalid IP found';
}
}
break;
case 'i':
$this->v2_i_block_found = true;
switch ($v2_break_feed[1]) {
case 'error':
$this->warnings[] = 'Query Error';
break;
case 'net-not-supported':
$this->warnings[] = 'Network not supported';
break;
case 'pong':
$this->warnings[] = 'PONG found on no ping';
}
break;
case '<': //Easy way to detect an HTML doc.
$this->warnings[] = 'HTML-like format detected';
}
}
else {
switch ($v2_break_feed[0]) {
case 'u':
case 'h':
case 'i':
case 'd': //Used by jon atkin's cache... (debug)
case 'ukhl': //Reserved
case 'uhc': //Reserved
$this->info->v2_cache = true;
$this->warnings[] = 'Incomplete data tag found';
break 2;
default:
$this->info->v1_cache = true;
}
if (stripos($line, 'ERROR: Network not supported') === 0) {
$this->warnings[] = 'Network not supported';
}
elseif (stripos($line, 'ERROR') === 0) {
$this->warnings[] = 'Query Error';
}
elseif (strpos($line, 'PONG') === 0) {
$this->warnings[] = 'PONG found on no ping';
}
elseif (stripos($line, 'http://') === 0) {
$this->info->url_count++;
$this->url_v1_found_in_cache = true;
}
elseif (stripos($line, '<') !== false) {
$this->warnings[] = 'HTML-like format detected';
}
elseif ($line[0] == '[') {
if ($this->ipv6_check($line)) {
$this->ip_v1_found_in_cache = true;
$this->info->host_count++;
}
else {
$this->warnings[] = 'Invalid IP found';
}
}
elseif (substr_count($line, '.') == 3 && strpos($line, ':') !== false) {
if ($this->ipv4_check($line)) {
$this->ip_v1_found_in_cache = true;
$this->info->host_count++;
}
else {
$this->warnings[] = 'Invalid IP found';
}
}
elseif (stripos($line, 'WARNING') === 0) {
$this->warnings[] = 'Warning message found';
}
else {
$this->warnings[] = 'Invalid data';
}
}
}
if (empty($this->warnings)) {
if (!$this->info->v2_cache) {
if ($this->network != 'gnutella' && $this->network != 'mute') {
$this->warnings[] = 'No GWC-type(v2) output detected';
}
elseif ($this->network == 'mute' && !$mute_cache) {
$this->warnings[] = 'URL is not a MUTE cache';
}
elseif ($this->url_v1_found_in_cache) {
$this->warnings[] = 'Invalid GWC-type(v1) output detected';
}
elseif (!$this->ip_v1_found_in_cache) {
$this->warnings[] = 'No GWC-type(v1) output detected';
}
}
elseif (!$this->ip_v2_found_in_cache && $this->v2_h_block_found) {
$this->warnings[] = 'Invalid GWC-type(v2) IP output detected';
}
elseif (!$this->url_v2_found_in_cache && $this->v2_u_block_found) {
$this->warnings[] = 'Invalid GWC-type(v2) URL output detected';
}
if (empty($this->warnings)) {
if (settings::UPDATE_SELF_TO_REMOTE) {
$this->obtain_socket_out($query_base.$query_net.$query_update_url, false);
}
$this->save('url');
$this->success = true;
}
}
}
else {
$this->warnings[] = 'Failed to connect';
}
}
}
else {
$this->warnings[] = 'Failed to connect';
}
if (!empty($this->warnings) && !$this->success) {
$this->info->gwc_variables['bad_url'] = $this->info->gwc_variables['url'];
$this->save('bad_url');
}
}
else {
$this->save('url');
$this->success = true;
}
}
}
}
else {
$this->warnings[] = 'URL is of this script';
}
}
}
class spec1 {
public $runtime;
public $execute;
function __construct($runtime) {
$this->runtime = $runtime;
try {
$this->decide();
}
catch (Exception $error) {
die('ERROR: '.$this->runtime->strip_chars($error->getMessage())."\r\n");
}
}
private function decide() {
if (!settings::ENABLE_V1) { throw new Exception('Specification 1 disabled'); }
if (!empty($this->runtime->warn)) { die($this->warn($this->runtime->warn)); }
if ($this->runtime->gwc_variables['ping']) { $this->ping(); }
if ($this->runtime->gwc_variables['getnetworks']) { $this->getnetworks(); }
if ($this->runtime->gwc_variables['ip'] !== false || $this->runtime->gwc_variables['ipv6'] !== false) { $this->cache_host(); }
if ($this->runtime->gwc_variables['url'] !== false) { $this->cache_url(); }
if ($this->runtime->gwc_variables['hostfile'] || $this->runtime->gwc_variables['get']) { $this->hosts(); }
if ($this->runtime->gwc_variables['urlfile'] || $this->runtime->gwc_variables['get']) { $this->urls(); }
if ($this->runtime->gwc_variables['statfile']) { $this->stats(); }
$this->runtime->resolve_services();
}
private function ping() {
echo('PONG '.settings::CACHE_NAME.' '.settings::CACHE_VERSION."\r\n");
}
private function getnetworks() {
echo('nets: '.implode('-', $this->runtime->settings->NETWORKS)."\r\n");
}
private function hosts() {
$grab = new data_manage($this->runtime, 'down', 'ip', $this->runtime->gwc_variables['net']);
if (!empty($grab->data->output)) {
foreach ($grab->data->output as $ip) {
list($host, $time) = explode('|', $ip);
$time_ = time() - $time;
echo($host."\r\n");
}
}
else { echo("0.0.0.0:0\r\n"); }
}
private function urls() {
$grab = new data_manage($this->runtime, 'down', 'url', $this->runtime->gwc_variables['net']);
if (!empty($grab->data->output)) {
foreach ($grab->data->output as $url) {
list($host, $time) = explode('|', $url);
$time_ = time() - $time;
echo($this->runtime->convert_out_of_set_chars($host)."\r\n");
}
}
else { echo('http://'.$this->runtime->convert_out_of_set_chars($this->runtime->env_variables['url'])."\r\n"); }
}
private function stats() {
$this->stats = new statistics($this->runtime, 'request', $this->runtime->gwc_variables['net']);
echo($this->stats->output());
}
private function cache_host() {
$update_host = new update($this->runtime, 'ip', $this->runtime->gwc_variables['net']);
echo("OK\r\n");
$this->execute['ok'] = true;
if (!empty($update_host->warnings)) {
$this->warn($update_host->warnings);
}
}
private function cache_url() {
$update_url = new update($this->runtime, 'url', $this->runtime->gwc_variables['net']);
if (isset($this->execute['ok']) == false) {
echo("OK\r\n");
}
if (!empty($update_url->warnings)) {
$this->warn($update_url->warnings);
}
}
private function warn($warnings) {
foreach ($warnings as $warning) {
echo('WARNING: '.$this->runtime->strip_chars($warning)."\r\n");
}
}
}
class spec2 {
public $runtime;
public $execute;
function __construct($runtime) {
$this->runtime = $runtime;
try {
$this->decide();
}
catch (Exception $error) {
die('I|ERROR|'.$this->runtime->strip_chars($error->getMessage())."\r\n");
}
}
private function decide() {
if (!settings::ENABLE_V2) { throw new Exception('Specification 2 disabled'); }
if (!empty($this->runtime->warn)) { die($this->warn($this->runtime->warn)); }
if ($this->runtime->gwc_variables['ping']) { $this->ping(); }
if ($this->runtime->gwc_variables['ping'] || $this->runtime->gwc_variables['getnetworks']) { $this->getnetworks(); }
if ($this->runtime->gwc_variables['ip'] !== false || $this->runtime->gwc_variables['ipv6'] !== false) { $this->cache_host(); }
if ($this->runtime->gwc_variables['url'] !== false) { $this->cache_url(); }
if ($this->runtime->gwc_variables['hostfile'] || $this->runtime->gwc_variables['get']) { $this->hosts(); }
if ($this->runtime->gwc_variables['urlfile'] || $this->runtime->gwc_variables['get']) { $this->urls(); }
if ($this->runtime->gwc_variables['statfile']) { $this->stats(); }
if ($this->runtime->gwc_variables['info']) { $this->extra('info'); }
if ($this->runtime->gwc_variables['support']) { $this->extra('support'); }
$this->runtime->resolve_services();
echo('I|access|period|3300'."\r\n");
}
private function ping() {
echo('I|pong|'.settings::CACHE_NAME.' '.settings::CACHE_VERSION.'|'.implode('-', $this->runtime->settings->NETWORKS)."\r\n");
}
private function getnetworks() {
echo('I|networks|'.implode('|', $this->runtime->settings->NETWORKS)."\r\n");
echo('I|nets|'.implode('-', $this->runtime->settings->NETWORKS)."\r\n");
}
private function hosts() {
$grab = new data_manage($this->runtime, 'down', 'ip', $this->runtime->gwc_variables['net']);
if (!empty($grab->data->output)) {
foreach ($grab->data->output as $ip) {
list($host, $time, , $cluster, $leaves, $uptime, $max_leaves, $vendor) = explode('|', $ip);
$time_ = time() - $time;
$cluster_ = ((!empty($cluster) && $this->runtime->gwc_variables['getclusters']) ? $cluster : '');
$leaves_ = (((!empty($leaves) || $leaves === '0') and $this->runtime->gwc_variables['getleaves']) ? $leaves : '');
$vendor_ = ((!empty($vendor) && $this->runtime->gwc_variables['getvendors']) ? $vendor : '');
$uptime_ = ((!empty($uptime) || $uptime === '0') and $this->runtime->gwc_variables['getuptime']) ? $uptime : '';
$max_leaves_ = ((!empty($max_leaves) || $max_leaves === '0') and $this->runtime->gwc_variables['getleaves']) ? $max_leaves : '';
$request_build = 'H|'.$host.'|'.$time_;
//Pattern used below to output the available data without 'ghost' || brackets:
if (strlen($cluster_) || strlen($leaves_) || strlen($vendor_) || strlen($uptime_) || strlen($max_leaves_)) {
if (strlen($cluster_)) {
$request_build .= '|'.$cluster_;
}
elseif (strlen($leaves_) || strlen($vendor_) || strlen($uptime_) || strlen($max_leaves_)) {
$request_build .= '|';
}
if (strlen($leaves_) || strlen($vendor_) || strlen($uptime_) || strlen($max_leaves_)) {
if (strlen($leaves_)) {
$request_build .= '|'.$leaves_;
}
elseif (strlen($vendor_) || strlen($uptime_) || strlen($max_leaves_)) {
$request_build .= '|';
}
if (strlen($vendor_) || strlen($uptime_) || strlen($max_leaves_)) {
if (strlen($vendor_)) {
$request_build .= '|'.$vendor_;
}
elseif (strlen($uptime_) || strlen($max_leaves_)) {
$request_build .= '|';
}
if (strlen($uptime_) || strlen($max_leaves_)) {
if (strlen($uptime_)) {
$request_build .= '|'.$uptime_;
}
elseif (strlen($max_leaves_)) {
$request_build .= '|';
}
if (strlen($max_leaves_)) {
$request_build .= '|'.$max_leaves_;
}
}
}
}
}
echo($request_build."\r\n");
}
}
else { echo('I|NO-HOSTS'."\r\n".'H|0.0.0.0:0'."\r\n"); }
}
private function urls() {
$grab = new data_manage($this->runtime, 'down', 'url', $this->runtime->gwc_variables['net']);
if (!empty($grab->data->output)) {
foreach ($grab->data->output as $url) {
list($host, $time) = explode('|', $url);
$time_ = time() - $time;
echo('U|'.$this->runtime->convert_out_of_set_chars($host).'|'.$time_."\r\n");
}
}
else { echo('I|NO-URL'."\r\n".'U|http://'.$this->runtime->convert_out_of_set_chars($this->runtime->env_variables['url'])."\r\n"); }
}
private function cache_host() {
$update_host = new update($this->runtime, 'ip', $this->runtime->gwc_variables['net']);
echo('I|update|OK'.(($update_host->success) ? ((!empty($update_host->warnings)) ? '|HOST|WARNING|'.$this->runtime->strip_chars(implode('; ', $update_host->warnings)) : '|HOST|GOOD') : '|HOST|WARNING|BAD|'.$this->runtime->strip_chars(implode('; ', $update_host->warnings)))."\r\n");
echo('I|update|period|'.(settings::EXPIRE_HOSTS * 3600)."\r\n"); $this->execute['update'] = true;
}
private function cache_url() {
$update_url = new update($this->runtime, 'url', $this->runtime->gwc_variables['net']);
echo('I|update|OK'.(($update_url->success) ? ((!empty($update_url->warnings)) ? '|URL|WARNING|'.$this->runtime->strip_chars(implode('; ', $update_url->warnings)) : '|URL|GOOD') : '|URL|WARNING|BAD|'.$this->runtime->strip_chars(implode('; ', $update_url->warnings)))."\r\n");
if ($this->execute['update'] == false) { echo('I|update|period|'.(settings::EXPIRE_HOSTS * 3600)."\r\n"); }
}
private function stats() {
$this->stats = new statistics($this->runtime, 'request', $this->runtime->gwc_variables['net']);
echo($this->stats->output());
}
private function extra($type) {
switch ($type) {
case 'info':
echo('I|name|'.settings::CACHE_NAME."\r\n");
echo('I|ver|'.settings::CACHE_VERSION."\r\n");
echo('I|vendor|'.settings::CACHE_VENDOR."\r\n");
echo('I|gwc-site|http://sourceforge.net/projects/beaconcache/'."\r\n");
echo('I|open-source|1'."\r\n");
$stats1 = $stats2 = $stats3 = array();
foreach ($this->runtime->settings->NETWORKS as $temp_net) {
$this->stats = new statistics($this->runtime, 'request', $temp_net);
$stats_out_dump = $this->stats->output();
echo('I|stats|'.$temp_net.'|'.implode('|', explode("\r\n", $stats_out_dump))."\r\n");
list($stats1[], $stats2[], $stats3[]) = explode("\r\n", $stats_out_dump);
}
echo('I|combined-stats|'.array_sum($stats1).'|'.array_sum($stats2).'|'.array_sum($stats3)."|\r\n");
break;
case 'support':
if (is_array($this->runtime->settings->NETWORKS)) {
foreach ($this->runtime->settings->NETWORKS as $network) {
echo('I|support|'.$network."\r\n");
}
}
if (is_array($this->runtime->settings->NETWORKS_ALT)) {
if (!empty($this->runtime->settings->NETWORKS_ALT)) {
foreach ($this->runtime->settings->NETWORKS_ALT as $alt_network=>$network) {
echo('I|alternate-net-names|'.$alt_network.'|'.$network."\r\n");
}
}
}
echo('I|storage-type|'.settings::STORAGE."\r\n");
echo('I|hosts-in|'.settings::HOSTS_IN."\r\n");
echo('I|hosts-out|'.settings::HOSTS_OUT."\r\n");
echo('I|urls-in|'.settings::URLS_IN."\r\n");
echo('I|urls-out|'.settings::URLS_OUT."\r\n");
echo('I|banned-urls-in|'.settings::BANNED_URLS_IN."\r\n");
echo('I|shuffle-hosts|'.settings::SHUFFLE_HOSTS."\r\n");
echo('I|shuffle-urls|'.settings::SHUFFLE_URLS."\r\n");
echo('I|expire-hosts|'.settings::EXPIRE_HOSTS."\r\n");
echo('I|expire-urls|'.settings::EXPIRE_URLS."\r\n");
echo('I|expire-banned-urls|'.settings::EXPIRE_BANNED_URLS."\r\n");
echo('I|default-net|'.settings::DEFAULT_NET."\r\n");
echo('I|socket-timeout|'.settings::TIMEOUT."\r\n");
echo('I|ip-as-url|'.((settings::IP_ALT_CACHES) ? '1' : '0')."\r\n");
echo('I|socket-non-80|'.((settings::NON_HTTP) ? '1' : '0')."\r\n");
echo('I|retry-urls|'.((settings::RETRY_URLS) ? '1' : '0')."\r\n");
echo('I|retry-bad-urls|'.((settings::RETRY_BAD_URLS) ? '1' : '0')."\r\n");
echo('I|web-front|'.((settings::WEB_FRONT) ? '1' : '0')."\r\n");
echo('I|blocks-no-useragent|'.((settings::BLOCK_NO_USER_AGENT) ? '1' : '0')."\r\n");
echo('I|url-adds|'.((settings::WEBFRONT_URL_ADDS) ? '1' : '0')."\r\n");
echo('I|stats-enabled|'.((settings::ENABLE_HIT_STATS) ? '1' : '0')."\r\n");
echo('I|client-stats-enabled|'.((settings::ENABLE_CLIENT_STATS) ? '1|throttle|'.settings::STATS_THROTTLE.'|flush-multiple|'.settings::STATS_CLIENT_FLUSH : '0')."\r\n");
echo('I|gwc-advertise|'.((settings::UPDATE_SELF_TO_REMOTE) ? '1' : '0')."\r\n");
echo('I|fsockopen|'.((settings::FSOCKOPEN) ? '1' : '0')."\r\n");
echo('I|crude-gwc-grading|'.((settings::CHECKS_ALLOWED) ? '1' : '0')."\r\n");
break;
}
}
private function warn($warnings) {
foreach ($warnings as $warned) {
echo('I|WARNING|'.$this->runtime->strip_chars($warned)."\r\n");
}
}
}
class spec_xml {
public $runtime;
private $xml;
public $execute;
function __construct($runtime) {
$this->runtime = $runtime;
$this->xml = new XMLWriter();
$this->xml->openMemory();
$this->xml->startDocument();
$this->xml->setIndent(true);
$this->xml->startElement('gwc');
$this->xml->writeAttribute('xmlns', 'http://beacon.grantgalitz.com/');
$this->xml->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$this->xml->writeAttribute('xsi:schemaLocation', 'http://beacon.grantgalitz.com/ http://beacon.grantgalitz.com/Xml-Spec.xsd');
$this->xml->startElement('instance');
$this->xml->writeAttribute('network', $this->runtime->gwc_variables['net']);
$this->xml->endElement();
try {
header('Content-Type: text/xml'); //This is XML...
$this->decide();
}
catch (Exception $error) {
$this->error(array($error->getMessage()));
}
$this->xml->endElement();
echo($this->xml->outputMemory());
}
private function decide() {
if (!settings::ENABLE_V3) {
throw new Exception('Specification 3 disabled');
return;
}
if (!empty($this->runtime->warn)) {
$this->warn($this->runtime->warn);
return;
}
if ($this->runtime->gwc_variables['ping']) { $this->ping(); }
if ($this->runtime->gwc_variables['ping'] || $this->runtime->gwc_variables['getnetworks']) { $this->getnetworks(); }
if ($this->runtime->gwc_variables['ip'] !== false || $this->runtime->gwc_variables['ipv6'] !== false) { $this->cache_host(); }
if ($this->runtime->gwc_variables['url'] !== false) { $this->cache_url(); }
if ($this->runtime->gwc_variables['hostfile'] || $this->runtime->gwc_variables['get']) { $this->hosts(); }
if ($this->runtime->gwc_variables['urlfile'] || $this->runtime->gwc_variables['get']) { $this->urls(); }
if ($this->runtime->gwc_variables['statfile']) { $this->stats(); }
if ($this->runtime->gwc_variables['info']) { $this->extra('info'); }
if ($this->runtime->gwc_variables['support']) { $this->extra('support'); }
$this->runtime->resolve_services();
$this->xml->startElement('period');
$this->xml->writeAttribute('type', 'access');
$this->xml->writeAttribute('limit', '3300');
$this->xml->endElement();
}
private function ping() {
$this->xml->startElement('pong');
$this->xml->writeAttribute('name', settings::CACHE_NAME);
$this->xml->writeAttribute('version', settings::CACHE_VERSION);
$this->xml->endElement();
$this->getnetworks();
}
private function getnetworks() {
static $networks_executed = false;
if (!$networks_executed) {
$this->xml->startElement('networks');
foreach ($this->runtime->settings->NETWORKS as $network) {
$this->xml->writeElement('network', $network);
}
$this->xml->endElement();
}
$networks_executed = true;
}
private function hosts() {
$grab = new data_manage($this->runtime, 'down', 'ip', $this->runtime->gwc_variables['net']);
if (!empty($grab->data->output)) {
$this->xml->startElement('hosts');
foreach ($grab->data->output as $ip) {
list($host, $time, , $cluster, $leaves, $uptime, $max_leaves, $vendor, $ip_version) = explode('|', $ip);
$time_ = time() - $time;
$cluster_ = ((!empty($cluster) && $this->runtime->gwc_variables['getclusters']) ? $cluster : '');
$leaves_ = (((!empty($leaves) || $leaves === '0') and $this->runtime->gwc_variables['getleaves']) ? $leaves : '');
$vendor_ = ((!empty($vendor) && $this->runtime->gwc_variables['getvendors']) ? $vendor : '');
$uptime_ = ((!empty($uptime) || $uptime === '0') and $this->runtime->gwc_variables['getuptime']) ? $uptime : '';
$max_leaves_ = ((!empty($max_leaves) || $max_leaves === '0') and $this->runtime->gwc_variables['getleaves']) ? $max_leaves : '';
$this->xml->startElement('host');
$this->xml->writeAttribute('type', 'ipv'.$ip_version);
$this->xml->writeAttribute('age', $time_);
if (strlen($cluster_)) {
$this->xml->writeAttribute('cluster', $cluster_);
}
if (strlen($leaves_)) {
$this->xml->writeAttribute('leaves', $leaves_);
}
if (strlen($vendor_)) {
$this->xml->writeAttribute('vendor', $vendor_);
}
if (strlen($uptime_)) {
$this->xml->writeAttribute('uptime', $uptime_);
}
if (strlen($max_leaves_)) {
$this->xml->writeAttribute('maximum', $max_leaves_);
}
$this->xml->text($host);
$this->xml->endElement();
}
$this->xml->endElement();
}
}
private function urls() {
$grab = new data_manage($this->runtime, 'down', 'url', $this->runtime->gwc_variables['net']);
if (!empty($grab->data->output)) {
$this->xml->startElement('urls');
foreach ($grab->data->output as $url) {
list($host, $time, ,$pong) = explode('|', $url);
$time_ = time() - $time;
$this->xml->startElement('url');
$this->xml->writeAttribute('age', $time_);
$this->xml->writeAttribute('pong', $pong);
$this->xml->text($host);
$this->xml->endElement();
}
$this->xml->endElement();
}
}
private function cache_host() {
$this->xml->startElement('update');
$this->xml->writeAttribute('type', 'ip');
$update_host = new update($this->runtime, 'ip', $this->runtime->gwc_variables['net']);
$this->xml->startElement('process');
$this->xml->writeAttribute('status', (($update_host->success) ? 'ok' : 'bad'));
$this->xml->endElement();
if (!empty($update_host->warnings)) {
$this->warn($update_host->warnings);
}
$this->xml->startElement('period');
$this->xml->writeAttribute('type', 'update');
$this->xml->writeAttribute('limit', settings::EXPIRE_HOSTS * 3600);
$this->xml->endElement();
$this->xml->endElement();
}
private function cache_url() {
$this->xml->startElement('update');
$this->xml->writeAttribute('type', 'url');
$update_url = new update($this->runtime, 'url', $this->runtime->gwc_variables['net']);
$this->xml->startElement('process');
$this->xml->writeAttribute('status', (($update_url->success) ? 'ok' : 'bad'));
$this->xml->endElement();
if (!empty($update_url->warnings)) {
$this->warn($update_url->warnings);
}
$this->xml->startElement('period');
$this->xml->writeAttribute('type', 'update');
$this->xml->writeAttribute('limit', settings::EXPIRE_URLS * 3600);
$this->xml->endElement();
$this->xml->endElement();
}
private function warn($warnings) {
foreach ($warnings as $warning) {
$this->xml->writeElement('warning', $warning);
}
}
private function error($errors) {
foreach ($errors as $error) {
$this->xml->writeElement('error', $error);
}
}
private function stats() {
$stats1 = $stats2 = $stats3 = array();
$this->xml->startElement('stats');
foreach ($this->runtime->settings->NETWORKS as $temp_net) {
$this->stats = new statistics($this->runtime, 'request', $temp_net);
$stats_out_dump = $this->stats->output();
$stats = explode("\r\n", $stats_out_dump);
$this->out_extra('stat', array('network'=>$temp_net, 'total-hits'=>$stats[0], 'hour-requests'=>$stats[1], 'hour-updates'=>$stats[2]));
$stats1[] = $stats[0]; $stats2[] = $stats[1]; $stats3[] = $stats[2];
}
$this->out_extra('stat', array('combined'=>count($this->runtime->settings->NETWORKS), 'total-hits'=>array_sum($stats1), 'hour-requests'=>array_sum($stats2), 'hour-updates'=>array_sum($stats3)));
$this->xml->endElement();
}
private function out_extra($group, $data) {
$this->xml->startElement($group);
foreach ($data as $key=>$value) {
$this->xml->writeAttribute($key, $value);
}
$this->xml->endElement();
}
private function extra($type) {
$this->xml->startElement(($type == 'info') ? 'infos' : 'supports');
switch ($type) {
case 'info':
$this->out_extra($type, array('name'=>settings::CACHE_NAME));
$this->out_extra($type, array('version'=>settings::CACHE_VERSION));
$this->out_extra($type, array('vendor'=>settings::CACHE_VENDOR));
$this->out_extra($type, array('gwc-site'=>'http://sourceforge.net/projects/beaconcache/'));
$this->out_extra($type, array('open-source'=>'yes'));
break;
case 'support':
if (is_array($this->runtime->settings->NETWORKS)) {
foreach ($this->runtime->settings->NETWORKS as $network) {
$this->out_extra($type, array('support'=>$network));
}
}
if (is_array($this->runtime->settings->NETWORKS_ALT)) {
if (!empty($this->runtime->settings->NETWORKS_ALT)) {
foreach ($this->runtime->settings->NETWORKS_ALT as $alt_network=>$network) {
$this->out_extra($type, array('alternate-net-names'=>$network, 'alt'=>$alt_network));
}
}
}
$this->out_extra($type, array('storage-type'=>settings::STORAGE));
$this->out_extra($type, array('hosts-in'=>settings::HOSTS_IN));
$this->out_extra($type, array('hosts-out'=>settings::HOSTS_OUT));
$this->out_extra($type, array('urls-in'=>settings::URLS_IN));
$this->out_extra($type, array('urls-out'=>settings::URLS_OUT));
$this->out_extra($type, array('banned-urls-in'=>settings::BANNED_URLS_IN));
$this->out_extra($type, array('shuffle-hosts'=>settings::SHUFFLE_HOSTS));
$this->out_extra($type, array('shuffle-urls'=>settings::SHUFFLE_URLS));
$this->out_extra($type, array('expire-hosts'=>settings::EXPIRE_HOSTS));
$this->out_extra($type, array('expire-urls'=>settings::EXPIRE_URLS));
$this->out_extra($type, array('expire-banned-urls'=>settings::EXPIRE_BANNED_URLS));
$this->out_extra($type, array('default-net'=>settings::DEFAULT_NET));
$this->out_extra($type, array('socket-timeout'=>settings::TIMEOUT));
$this->out_extra($type, array('ip-as-url'=>((settings::IP_ALT_CACHES) ? 'yes' : 'no')));
$this->out_extra($type, array('socket-non-80'=>((settings::NON_HTTP) ? 'yes' : 'no')));
$this->out_extra($type, array('retry-urls'=>((settings::RETRY_URLS) ? 'yes' : 'no')));
$this->out_extra($type, array('retry-bad-urls'=>((settings::RETRY_BAD_URLS) ? 'yes' : 'no')));
$this->out_extra($type, array('web-front'=>((settings::WEB_FRONT) ? 'yes' : 'no')));
$this->out_extra($type, array('blocks-no-useragent'=>((settings::BLOCK_NO_USER_AGENT) ? 'yes' : 'no')));
$this->out_extra($type, array('url-adds'=>((settings::WEBFRONT_URL_ADDS) ? 'yes' : 'no')));
$this->out_extra($type, array('stats-enabled'=>((settings::ENABLE_HIT_STATS) ? 'yes' : 'no')));
$this->out_extra($type, array('client-stats-enabled'=>((settings::ENABLE_CLIENT_STATS) ? 'yes' : 'no'), 'throttle'=>settings::STATS_THROTTLE, 'flush-multiple'=>settings::STATS_CLIENT_FLUSH));
$this->out_extra($type, array('gwc-advertise'=>((settings::UPDATE_SELF_TO_REMOTE) ? 'yes' : 'no')));
$this->out_extra($type, array('fsockopen'=>((settings::FSOCKOPEN) ? 'yes' : 'no')));
$this->out_extra($type, array('crude-gwc-grading'=>((settings::CHECKS_ALLOWED) ? 'yes' : 'no')));
break;
}
$this->xml->endElement();
}
}
class gwc {
public $externals;
public $spec;
public $warn;
public $error;
public $env_variables;
public $gwc_variables;
public $settings;
public $pong;
public $host_count;
public $url_count;
public $v1_cache;
public $v2_cache;
public $final_ip;
public $ip;
public $ipv6;
public $url_ip;
private $banning;
private $gwc_connect;
function __construct() {
gwc::server_variables();
gwc::check_address();
gwc::get_vars();
gwc::process_variables();
gwc::specification();
}
public function strip_chars($string, $header_group=false) {
$string = (string)$string;
$string = str_ireplace("\r", '', $string);
$string = str_ireplace("\n", '', $string);
$string = str_ireplace("\0", '', $string);
$string = str_ireplace("\v", '', $string);
$string = str_ireplace("\f", '', $string);
$string = str_ireplace("\t", '', $string);
$string = str_ireplace('|', '', $string);
$string = (get_magic_quotes_gpc() && $header_group) ? stripslashes($string) : $string; //If system has directive set, decode string...
return $string;
}
private function server_variables() {
if (isset($_SERVER)) {
(isset($_SERVER['REMOTE_ADDR'])) ? $this->env_variables['client_ip'] = $_SERVER['REMOTE_ADDR'] : die('ERROR: Remote IP not detected!');
(isset($_SERVER['SERVER_PORT'])) ? $this->env_variables['port'] = $_SERVER['SERVER_PORT'] : $this->env_variables['port'] = 80;
(isset($_SERVER['HTTP_USER_AGENT'])) ? $this->env_variables['user_agent'] = $_SERVER['HTTP_USER_AGENT'] : $this->env_variables['user_agent'] = false;
(isset($_SERVER['SERVER_NAME'])) ? $this->env_variables['server_name'] = $_SERVER['SERVER_NAME'] : ((isset($_SERVER['SERVER_HOST'])) ? $this->env_variables['server_name'] = $_SERVER['SERVER_HOST'] : die('ERROR: Server name not detected!'));
(isset($_SERVER['PHP_SELF'])) ? ($this->env_variables['url'] = $this->env_variables['server_name'].(($this->env_variables['port'] != 80) ? ':'.$this->env_variables['port'] : '').$_SERVER['PHP_SELF']) : die('ERROR: File directory reference not detected!');
$this->env_variables['give_rem_ip'] = (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $this->env_variables['client_ip'];
$this->env_variables['https'] = (isset($_SERVER['HTTPS'])) ? $_SERVER['HTTPS'] : '';
(!empty($this->env_variables['https'])) ? die('ERROR: HTTPS is not allowed for GWebCache connections.') : $this->env_variables['https'] = 'http://'; //HTTPS is not allowed, as pretty much almost all GWebCaches cannot test each other with HTTPS through sockets.
}
else {
die('ERROR: Environment variables missing!');
}
$this->settings = new settings();
if (empty($this->settings->NETWORKS) or (!settings::ENABLE_V1 && !settings::ENABLE_V2)) { die('ERROR: Offline'); }
}
public function convert_out_of_set_chars($url) {
if (strlen($url) >= 1) {
$url = urlencode($url); //To encode out-of-set chars...
$url_decode_array = array(
'%21'=>'!',
'%2A'=>'*',
'%27'=>'\'',
'%28'=>'(',
'%29'=>')',
'%3B'=>';',
'%3A'=>':',
'%40'=>'@',
'%26'=>'&',
'%3D'=>'=',
'%2B'=>'+',
'%24'=>'$',
'%2C'=>',',
'%2F'=>'/',
'%3F'=>'?',
'%25'=>'%',
'%23'=>'#',
'%5B'=>'[',
'%5D'=>']',
'+'=>'%20'
);
foreach ($url_decode_array as $key=>$value) {
$url = str_replace($key, $value, $url); //To de-encode reserved filepath chars....
}
}
return $url;
}
public function check_address() {
if (settings::CACHE_ADDRESS) {
if ('http://'.$this->env_variables['url'] != settings::CACHE_ADDRESS) {
header('HTTP/1.1 301 Moved Permanently');
die(header('Location: '.$this->convert_out_of_set_chars(settings::CACHE_ADDRESS)));
}
}
}
private function get_vars() {
if (isset($_GET)) {
foreach ($_GET as $key=>$value) {
$key = strtolower($key);
$this->externals[$key] = (isset($value)) ? $this->strip_chars($value, true) : false;
}
}
}
private function determine_bool($id, $reverse=false) {
$this->gwc_variables[$id] = (isset($this->externals[$id])) ? (($this->externals[$id] !== '0') ? true : false) : (($reverse) ? true : false);
$this->gwc_connect = (isset($this->externals[$id])) ? true : $this->gwc_connect;
}
private function determine_exact($id, $id_mask='') {
$this->gwc_variables[((strlen((string)$id_mask)) ? $id_mask : $id)] = (isset($this->externals[$id])) ? $this->externals[$id] : ((isset($this->gwc_variables[((strlen((string)$id_mask)) ? $id_mask : $id)])) ? $this->gwc_variables[((strlen((string)$id_mask)) ? $id_mask : $id)] : false);
$this->gwc_connect = (isset($this->externals[$id])) ? true : $this->gwc_connect;
}
private function process_variables() {
$this->gwc_connect = false;
$this->gwc_variables = array();
if (isset($this->externals)) {
//Preparing GWC parameters:
$this->determine_exact('url1', 'url');
$this->determine_exact('url');
$this->determine_exact('ip1', 'ip');
$this->determine_exact('ip');
$this->determine_exact('client');
$this->determine_exact('version');
$this->determine_exact('net');
$this->determine_exact('cluster');
$this->determine_exact('x_leaves');
$this->determine_exact('spec');
$this->determine_exact('pv');
$this->determine_bool('get');
$this->determine_bool('hostfile');
$this->determine_bool('urlfile');
$this->determine_bool('bfile');
$this->determine_bool('statfile');
$this->determine_bool('gwcs');
$this->determine_bool('ping');
$this->determine_bool('info');
$this->determine_bool('support');
$this->determine_bool('multi'); //Used for compatibility workaround with Skulls GWC.
$this->determine_bool('cache'); //Used as an added check to block a cache from updating an IP address.
$this->determine_bool('update');
//Extensions to specification 2, via 2.1:
$this->determine_bool('getclusters', true); //Output clusters (Spec 2 default is to do so).
$this->determine_bool('getleaves'); //Output leaf counts.
$this->determine_bool('getnetworks'); //Output supported networks (Automatically given on v2 ping requests).
$this->determine_bool('getvendors'); //Output vendor codes for host requests.
$this->determine_exact('uptime'); //Input for uptime.
$this->determine_bool('getuptime'); //Output for uptime.
$this->determine_exact('x_max'); //Input for maximum leaf slots available.
//XML Output:
$this->determine_bool('xml'); //Request option for whether to output XML-style or not.
$this->determine_exact('ipv6'); //IP update in IPv6 format ('ip' param can still be passed with it for IPv4 alternate).
$this->determine_bool('getv6'); //Allowing IPv6 addresses in requests.
}
}
private function specification() {
if (!empty($this->gwc_variables) && $this->gwc_connect) {
$this->warn = array();
$this->spec = 1; //ALWAYS default to GWebCache specification 1.
if ($this->gwc_variables['client'] === false) {
$this->warn[] = 'Client Name Required';
}
elseif (strlen($this->gwc_variables['client']) <= 4) {
if (strlen($this->gwc_variables['client']) < 4) {
$this->warn[] = 'Improper Client Name';
}
elseif ($this->gwc_variables['version'] === false || strlen($this->gwc_variables['version']) === 0) {
$this->warn[] = 'Version Number Required';
}
}
elseif (strlen($this->gwc_variables['client']) > 20) {
$this->warn[] = 'Improper Client Name';
}
if ($this->gwc_variables['version'] !== false && strlen($this->gwc_variables['version']) > 16) {
$this->warn[] = 'Improper Version Length';
}
if ($this->gwc_variables['bfile']) {
$this->gwc_variables['hostfile'] = true;
$this->gwc_variables['urlfile'] = true;
}
elseif ($this->gwc_variables['gwcs']) {
$this->gwc_variables['urlfile'] = true;
}
if ($this->gwc_variables['net'] === false) {
$this->gwc_variables['net'] = settings::DEFAULT_NET;
}
elseif (strlen($this->gwc_variables['net']) === 0) {
$this->gwc_variables['net'] = settings::DEFAULT_NET;
$this->spec = 2;
}
else {
$this->gwc_variables['net'] = strtolower($this->gwc_variables['net']);
$this->spec = 2;
}
if ($this->gwc_variables['get']) {
$this->spec = 2;
}
elseif ($this->gwc_variables['info']) {
$this->spec = 2;
}
elseif ($this->gwc_variables['support']) {
$this->spec = 2;
}
elseif ($this->gwc_variables['multi']) {
$this->spec = 2;
}
elseif (isset($this->externals['getclusters'])) {
$this->spec = 2;
}
elseif ($this->gwc_variables['getleaves']) {
$this->spec = 2;
}
elseif ($this->gwc_variables['getnetworks']) {
$this->spec = 2;
}
elseif ($this->gwc_variables['getvendors']) {
$this->spec = 2;
}
elseif ($this->gwc_variables['uptime'] !== false) {
$this->spec = 2;
}
elseif ($this->gwc_variables['getuptime']) {
$this->spec = 2;
}
if ($this->gwc_variables['ipv6'] !== false) {
$this->spec = 2;
/*if ($this->gwc_variables['ip'] === false) {
$this->warn[] = 'IPv6 not yet supported'; //As update class only has ipv4 processing...
}*/
}
if ($this->gwc_variables['update'] || $this->gwc_variables['cluster'] !== false || $this->gwc_variables['x_leaves'] !== false || $this->gwc_variables['uptime'] !== false || $this->gwc_variables['x_max'] !== false) {
$this->spec = 2;
if ($this->gwc_variables['x_leaves'] !== false) {
(ctype_digit($this->gwc_variables['x_leaves'])) ? ((((int)$this->gwc_variables['x_leaves']) >= 2048) ? $this->gwc_variables['x_leaves'] = false : $this->gwc_variables['x_leaves'] = $this->gwc_variables['x_leaves']) : $this->warn[] = 'Bad leaf count';
}
if ($this->gwc_variables['x_max'] !== false) {
(ctype_digit($this->gwc_variables['x_max'])) ? ((((int)$this->gwc_variables['x_max']) >= 2048) ? $this->gwc_variables['x_max'] = false : $this->gwc_variables['x_max'] = $this->gwc_variables['x_max']) : $this->warn[] = 'Bad maximum leaf slots count';
}
if ($this->gwc_variables['uptime'] !== false) {
(ctype_digit($this->gwc_variables['uptime'])) ? ((((int)$this->gwc_variables['uptime']) >= 31536000) ? $this->gwc_variables['uptime'] = false : $this->gwc_variables['uptime'] = $this->gwc_variables['uptime']) : $this->warn[] = 'Bad uptime count';
}
if ($this->gwc_variables['cluster'] !== false) {
$this->gwc_variables['cluster'] = (strlen($this->gwc_variables['cluster']) > 256) ? false : $this->gwc_variables['cluster'];
}
if ($this->gwc_variables['ip'] === false && $this->gwc_variables['ipv6'] === false) {
if ($this->gwc_variables['cluster'] !== false || $this->gwc_variables['x_leaves'] !== false || $this->gwc_variables['uptime'] !== false || $this->gwc_variables['x_max'] !== false) {
$this->warn[] = 'Improper IP Update';
}
elseif ($this->gwc_variables['update'] && $this->gwc_variables['url'] === false) {
$this->warn[] = 'Improper Update';
}
}
}
if ($this->gwc_variables['spec']) {
if (ctype_digit($this->gwc_variables['spec'])) {
$this->spec = ($this->gwc_variables['spec'] == 1 || $this->gwc_variables['spec'] == 2) ? ((int) $this->gwc_variables['spec']) : $this->spec;
}
}
if ($this->gwc_variables['pv']) {
if (ctype_digit($this->gwc_variables['pv'])) {
if ($this->gwc_variables['pv'] < $this->spec && $this->gwc_variables['pv'] >= 1) {
$this->spec = (int) $this->gwc_variables['pv'];
}
}
}
if ($this->gwc_variables['xml']) {
$this->spec = 3;
}
if ($this->gwc_variables['client'] !== false) {
if ($this->gwc_variables['ip'] === false && $this->gwc_variables['url'] === false && $this->gwc_variables['hostfile'] == false &&
$this->gwc_variables['urlfile'] == false && $this->gwc_variables['statfile'] == false && $this->gwc_variables['gwcs'] == false && $this->gwc_variables['ping'] == false &&
$this->gwc_variables['get'] == false && $this->gwc_variables['info'] == false && $this->gwc_variables['support'] == false) {
$this->warn[] = 'Incomplete Request';
}
$this->gwc_variables['vendor_only'] = substr($this->gwc_variables['client'], 0, 4); //To avoid overwrites from user-agent matchings on specific vendor codes.
if ($this->env_variables['user_agent']) {
//Client vendor code overrides for finding clones, fakes, mod, etc:
if ('RAZA' == substr($this->gwc_variables['client'], 0, 4) and (strpos($this->env_variables['user_agent'], 'Shareaza') !== 0 || stripos($this->env_variables['user_agent'], 'pro') !== false || stripos($this->env_variables['user_agent'], 'lite') !== false)) {
$this->gwc_variables['client'] = $this->strip_chars($this->env_variables['user_agent']);
$this->gwc_variables['version'] = false;
}
elseif ('LIME' == substr($this->gwc_variables['client'], 0, 4) && strpos($this->env_variables['user_agent'], 'LimeWire') === 0 && strpos($this->env_variables['user_agent'], '(Cabos/') !== false) {
$this->gwc_variables['client'] = 'CABO';
}
if ($this->gwc_variables['client'] == 'MUTE' && stripos($this->env_variables['user_agent'], 'Mutella') !== false) {
$this->gwc_variables['client'] = 'MTLL';
}
}
}
$this->headers();
$this->network();
$this->banning = new client_check($this);
($this->spec == 1) ? $this->proto_1() : (($this->spec == 2) ? $this->proto_2() : $this->proto_xml());
}
else { (settings::WEB_FRONT) ? $this->web_front() : die('This is '.settings::CACHE_NAME.' '.settings::CACHE_VERSION); }
}
private function headers() {
header('Content-Type: text/plain');
header('X-Remote-IP: '.$this->env_variables['give_rem_ip']);
header('X-GWC-URL: http://'.$this->env_variables['url']);
}
private function proto_1() {
$this->override_default_network();
$this->warn = $this->banning->bans($this->warn);
$handle_spec1 = new spec1($this);
}
private function proto_2() {
$this->warn = $this->banning->bans($this->warn);
$handle_spec2 = new spec2($this);
}
private function proto_xml() {
$this->warn = $this->banning->bans($this->warn);
$handle_xml = new spec_xml($this);
}
private function web_front() {
$webfront = new web_front($this);
}
private function override_default_network() {
if (!empty($this->settings->NET_SPEC1)) {
if ($this->gwc_variables['client'] !== false) {
$joined_vend = $this->gwc_variables['client'];
if ($this->gwc_variables['version']) {
$joined_vend .= $this->gwc_variables['version'];
}
}
else { $joined_vend = false; }
foreach ($this->settings->NET_SPEC1 as $key=>$value) {
if ($joined_vend !== false) {
if (substr($joined_vend, 0, strlen($key)) == $key) {
$this->gwc_variables['net'] = $value;
}
}
else { break; }
}
}
}
private function network() {
if (!empty($this->settings->NETWORKS_ALT)) {
if (array_key_exists($this->gwc_variables['net'], $this->settings->NETWORKS_ALT)) {
$this->gwc_variables['net'] = $this->settings->NETWORKS_ALT[$this->gwc_variables['net']];
}
}
if (!in_array($this->gwc_variables['net'], $this->settings->NETWORKS)) { die('ERROR: Network not supported'); }
}
public function resolve_services() {
//Run retry list and update stats...
$this->stats = new statistics($this, (($this->gwc_variables['ip'] !== false || $this->gwc_variables['url'] !== false) ? 'update' : 'request'), $this->gwc_variables['net']);
$this->stats->update();
$update_retry = new update($this, 'retry', $this->gwc_variables['net']);
$this->stats = new statistics($this, 'client', $this->gwc_variables['net']);
$this->stats->update();
$this->stats = new statistics($this, 'client');
$this->stats->update();
}
}
class web_front {
private $settings;
private $network;
function __construct($runtime) {
$this->runtime = $runtime;
$this->runtime->env_variables['url'] = $this->runtime->convert_out_of_set_chars($this->runtime->env_variables['url']);
if ($this->check_xhtml_support()) {
$this->display();
}
else {
$this->no_support();
}
}
private function convert_age($timestamp) {
$timestamp_diff = ((time() - (int)$timestamp) > 0) ? (time() - (int)$timestamp) : 0;
$hour = floor($timestamp_diff / 3600);
$minute_handle = $timestamp_diff - ($hour * 3600);
$minute = floor($minute_handle / 60);
$second = $minute_handle - ($minute * 60);
return $hour.':'.$minute.':'.$second;
}
private function convert_name($client) {
$client = (strlen($client) > 20) ? substr($client, 0, 20).'...' : $client; $matched = false;
if (strlen($client) >= 1) {
$client = htmlentities($client);
if (!empty($this->runtime->settings->VENDOR_CODE_MATCHINGS)) {
foreach ($this->runtime->settings->VENDOR_CODE_MATCHINGS as $known_client=>$details) {
if (strlen($client) >= strlen($known_client)) {
if ($known_client == substr($client , 0, strlen($known_client))) {
list($name, $url) = $details;
$client = str_replace($known_client, $name.' ', $client);
if ($url !== false) { $client = '<a href="'.$url.'" class="table_address">'.$client.'</a>'; }
$matched = true; break;
}
}
}
}
if (!$matched) {
if (stripos($client, 'TEST') === 0) {
$client = str_replace($client, 'WebCache( '.substr($client, 4).' )', $client);
}
else {
$client = str_replace($client, '<span class="shadow_text">Unknown( '.$client.' )</span>', $client);
}
}
}
return $client;
}
private function convert_pong($pong) {
$pong = htmlentities($pong);
if (strlen($pong) >= 1) {
$known_pongs = array(
'Cachechu'=>'http://code.google.com/p/cachechu/',
'GWebCache'=>'http://www.gnucleus.com/gwebcache/',
'jumswebcache'=>'http://www1.mager.org/GWebCache/',
'GhostWhiteCrab'=>'http://wiki.limewire.org/index.php?title=GhostWhiteCrab',
'PHPGnuCacheII'=>'http://gwcii.sourceforge.net/',
'Bazooka'=>'http://www.bazookanetworks.com/',
'Skulls'=>'http://sourceforge.net/projects/skulls/',
'Beacon Cache'=>'http://sourceforge.net/projects/beaconcache/',
'GERRY'=>'http://www.edazzle.net/',
'Lynn'=>'https://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=7846&lngWId=4'
);
foreach ($known_pongs as $known_pong=>$url) {
if (strlen($pong) >= strlen($known_pong)) {
if ($known_pong == substr($pong , 0, strlen($known_pong))) {
$pong = '<a href="'.$url.'" class="table_address">'.$pong.'</a>';
break;
}
}
}
}
return $pong;
}
private function grab_hosts(&$track) {
$grab = new data_manage($this, 'down', 'ip', $this->network);
?>
<tr>
<td class="table_top_cell">
Hosts<?php echo(((!empty($grab->data->contents)) ? ' (Out of '.count($grab->data->contents).')' : '')); ?>:
</td>
</tr>
<tr>
<td>
<table class="sub_table">
<?php
if (!empty($grab->data->contents)) {
?>
<tr class="bottom_rows">
<td class="cell1">Address:</td>
<td class="cell2">Client:</td>
<td class="cell3">Age (<abbr title="Hours:Minutes:Seconds">h:m:s</abbr>):</td>
</tr>
<?php
foreach ($grab->data->contents as $ip) {
$ip = trim($ip);
$client = ''; $host = ''; $timestamp = 0; $leaves = ''; $extras = array();
list($host, $timestamp, $client, /*$cluster*/, $leaves, $uptime, $max_leaves) = explode('|', $ip);
if (!empty($uptime) || $uptime === '0') { $extras[] = '<abbr title="uptime">u</abbr>:'.$this->convert_age(time() - ((int)$uptime)); }
if (!empty($leaves) || $leaves === '0') { $extras[] = '<abbr title="current leaves">l</abbr>:'.$leaves; }
if (!empty($max_leaves) || $max_leaves === '0') { $extras[] = '<abbr title="maximum leaves">m</abbr>:'.$max_leaves; }
echo("\t\t\t\t\t\t".'<tr class="table_cell'.((!$track) ? '' : '2').'"><td class="cell1"><a href="'.$this->network.':host:'.$host.'" class="table_address">'.$host.'</a>'.((!empty($extras)) ? ' ( '.implode(', ', $extras).' )' : '').'</td><td class="cell2">'.$this->convert_name($client).'</td><td class="cell3">'.$this->convert_age($timestamp).'</td></tr>'."\r\n");
(!$track) ? $track = true : $track = false;
}
}
else { echo("\t\t\t\t\t\t".'<tr class="no_list"><td>No '.htmlentities($this->network).' hosts stored.</td></tr>'."\r\n"); }
?>
</table>
</td>
</tr>
<?php
}
private function shorten_url($url) {
if (strlen($url) > 8) {
$url = substr($url, 7);
if (strpos($url, '/')) { $url = substr($url, 0, strpos($url, '/')); }
$url = htmlentities($url);
}
return $url;
}
private function grab_urls(&$track) {
$grab = new data_manage($this, 'down', 'url', $this->network);
?>
<tr>
<td class="table_top_cell">
URLs<?php echo(((!empty($grab->data->contents)) ? ' (Out of '.count($grab->data->contents).')' : '')); ?>:
</td>
</tr>
<tr>
<td>
<table class="sub_table">
<?php
if (!empty($grab->data->contents)) {
?>
<tr class="bottom_rows">
<td class="cell1">Address:</td>
<td class="cell2">Cache:</td>
<td class="cell2">Submission By:</td>
<td class="cell3">Age (<abbr title="Hours:Minutes:Seconds">h:m:s</abbr>):</td>
</tr>
<?php
foreach ($grab->data->contents as $url) {
$url = trim($url);
$client = ''; $$host_unsafe = ''; $timestamp = 0;
list($host_unsafe, $timestamp, $client, $pong) = explode('|', $url);
(empty($pong)) ? $pong = '[Unknown]' : (strlen($pong) > 40) ? $pong = substr($pong, 0, 40) : $pong = $pong;
$host = $this->runtime->convert_out_of_set_chars($host_unsafe);
echo("\t\t\t\t\t\t".'<tr class="table_cell'.((!$track) ? '' : '2').'"><td class="cell1">'.((settings::ADD_URL_TO_SHAREAZA) ? '<a href="shareaza:gwc:'.$host.'" class="table_address no_underline">+</a> ' : '').'<a href="'.$host.'" class="table_address">'.$this->shorten_url($host).'</a>'.((settings::CHECKS_ALLOWED) ? ' <a href="http://'.htmlentities($this->runtime->env_variables['url']).'?display='.$this->query_safe($this->network).'&query='.$this->query_safe($host_unsafe).'" class="table_address no_underline">*</a>' : '').'</td><td class="cell2">'.$this->convert_pong($pong).'</td><td class="cell2">'.$this->convert_name($client).'</td><td class="cell3">'.$this->convert_age($timestamp).'</td></tr>'."\r\n");
$track = (!$track) ? true : false;
}
}
else { echo("\t\t\t\t\t\t".'<tr class="no_list"><td>No '.htmlentities($this->network).' URLs stored.</td></tr>'."\r\n"); }
?>
</table>
</td>
</tr>
<?php
}
private function url_add(&$track, $url_to_add) {
$this->runtime->gwc_variables['client'] = 'URL-ADD';
$this->runtime->gwc_variables['url'] = $url_to_add;
$update_url = new update($this->runtime, 'url', $this->network);
if (isset($update_url->warnings[0])) {
?>
<tr class="table_top_cell">
<td class="red">Submission Failed</td>
</tr>
<tr class="table_cell<?php echo(((!$track) ? '' : '2')); $track = (!$track) ? true : false; ?>">
<td class="cell2">Error Message: <span class="yellow"><?php echo($update_url->warnings[0]); ?></span></td>
</tr>
<?php
}
else {
?>
<tr class="table_top_cell">
<td class="green">Submission Passed</td>
</tr>
<?php
$this->check_url($track, $url_to_add);
}
}
private function check_url(&$track, $url_to_check) {
$grab = new data_manage($this, 'down', 'url', $this->network);
if (!empty($grab->data->contents)) {
foreach ($grab->data->contents as $url) {
$url = trim($url);
$client = ''; $host = ''; $timestamp = 0; $host_count = 0; $url_count = 0; $grade = 100;
list($host, $timestamp, $client, $pong, $host_count, $url_count, $v1_support, $v2_support) = explode('|', $url);
(empty($pong)) ? $pong = '[Unknown]' : (strlen($pong) > 40) ? $pong = substr($pong, 0, 40) : $pong = $pong;
$host_count = (!$host_count) ? 0 : $host_count;
$url_count = (!$url_count) ? 0 : $url_count;
if ($host == $url_to_check) {
$host = $this->runtime->convert_out_of_set_chars($host);
if ($host_count == 0 || $host_count > 500) {
$grade -= 30;
}
elseif ($host_count < 5 || $host_count > 250) {
$grade -= 15;
}
elseif ($host_count < 10 || $host_count > 100) {
$grade -= 10;
}
if ($url_count == 0) {
$grade -= 20;
}
elseif ($url_count > 500) {
$grade -= 30;
}
elseif ($url_count == 1 || $url_count > 250) {
$grade -= 15;
}
elseif ($url_count < 10 || $url_count > 100) {
$grade -= 5;
}
if (!strlen($pong)) {
$grade -= 20;
}
if (((bool)$v1_support) && ((bool)$v2_support)) {
$grade -= 30;
}
$grade = ($grade > 0) ? $grade : 0;
?>
<tr>
<td>
<table class="sub_table">
<tr class="bottom_rows">
<td class="cell1">Address:</td>
<td class="cell2">Cache:</td>
<td class="cell2">Submission By:</td>
<td class="cell3">Age (<abbr title="Hours:Minutes:Seconds">h:m:s</abbr>):</td>
</tr>
<?php
echo("\t\t\t\t\t\t".'<tr class="table_cell'.((!$track) ? '' : '2').'"><td class="cell1">'.((settings::ADD_URL_TO_SHAREAZA) ? '<a href="shareaza:gwc:'.$host.'" class="table_address no_underline">+</a> ' : '').'<a href="'.$host.'" class="table_address">'.$this->shorten_url($host).'</a></td><td class="cell2">'.$this->convert_pong($pong).'</td><td class="cell2">'.$this->convert_name($client).'</td><td class="cell3">'.$this->convert_age($timestamp).'</td></tr>'."\r\n");
$track = (!$track) ? true : false;
?>
</table>
</td>
</tr>
<tr>
<td class="table_top_cell">
Quality Check:
</td>
</tr>
<tr>
<td>
<table id="cell_debug" class="sub_table">
<tr class="table_cell<?php echo(((!$track) ? '' : '2')); $track = (!$track) ? true : false; ?>">
<td class="cell_debug_head">V1 On Query:</td>
<td><?php echo(((bool)$v1_support) ? 'true' : 'false'); ?></td>
</tr>
<tr class="table_cell<?php echo(((!$track) ? '' : '2')); $track = (!$track) ? true : false; ?>">
<td class="cell_debug_head">V2 On Query:</td>
<td><?php echo(((bool)$v2_support) ? 'true' : 'false'); ?></td>
</tr>
<tr class="table_cell<?php echo(((!$track) ? '' : '2')); $track = (!$track) ? true : false; ?>">
<td class="cell_debug_head">Host Count:</td>
<td><?php echo((string)$host_count); ?></td>
</tr>
<tr class="table_cell<?php echo(((!$track) ? '' : '2')); $track = (!$track) ? true : false; ?>">
<td class="cell_debug_head">URL Count:</td>
<td><?php echo((string)$url_count); ?></td>
</tr>
<tr class="table_cell<?php echo(((!$track) ? '' : '2')); $track = (!$track) ? true : false; ?>">
<td class="cell_debug_head">Final Grade:</td>
<td class="<?php echo((string)($grade >= 70) ? (($grade >= 80) ? 'green' : 'yellow') : 'red'); ?>"><?php echo($grade); ?></td>
</tr>
</table>
</td>
</tr>
<?php
return;
}
}
echo("\t\t\t".'<tr class="no_list"><td>URL '.htmlentities($url_to_check).' not found.</td></tr>'."\r\n");
}
else { echo("\t\t\t".'<tr class="no_list"><td>No '.htmlentities($this->network).' URLs stored.</td></tr>'."\r\n"); }
}
private function client_stats(&$color_track, $network='') {
if (settings::ENABLE_CLIENT_STATS) {
$count_grand_total = 0; $client_count = $client_stats = array();
$stats_download = new data_manage($this, 'down', 'stats_client', $network);
if (!empty($stats_download->data->contents)) {
while (count($stats_download->data->contents) > settings::STATS_THROTTLE) {
array_shift($stats_download->data->contents);
}
if (!empty($stats_download->data->contents)) {
foreach ($stats_download->data->contents as $client_line) {
list($client_vend, $ip, $url, $ping, $get, $stats) = explode('|', $client_line);
$client_stats[$client_vend] = (!isset($client_stats[$client_vend])) ? array( 0, 0, 0, 0, 0, 0) : $client_stats[$client_vend];
$client_stats[$client_vend] = array(
0=>(($ip === '1') ? $client_stats[$client_vend][0] + 1 : $client_stats[$client_vend][0]),
1=>(($url === '1') ? $client_stats[$client_vend][1] + 1 : $client_stats[$client_vend][1]),
2=>(($ping === '1') ? $client_stats[$client_vend][2] + 1 : $client_stats[$client_vend][2]),
3=>(($get === '1') ? $client_stats[$client_vend][3] + 1 : $client_stats[$client_vend][3]),
4=>(($stats === '1') ? $client_stats[$client_vend][4] + 1 : $client_stats[$client_vend][4]),
5=>($client_stats[$client_vend][5] + 1)
);
$count_grand_total++;
}
foreach ($client_stats as $client=>$info) {
$client_count[$client] = $info[5];
}
natcasesort($client_count);
}
}
if (!empty($client_stats)) {
?>
<tr>
<td class="table_top_cell">
Client Hits<?php if ($count_grand_total !== 0) { echo(' (Out of '.$count_grand_total.')'); } ?>:
</td>
</tr>
<tr>
<td>
<table class="sub_table">
<tr class="bottom_rows">
<td class="cell1">Clients:</td>
<td class="cell2">IP Updates:</td>
<td class="cell2">URL Updates:</td>
<td class="cell2">Pings:</td>
<td class="cell2">Requests:</td>
<td class="cell2">Other:</td>
<td class="cell3">Total Hits:</td>
</tr>
<?php
foreach (array_reverse($client_count) as $client=>$count) {
?>
<tr class="table_cell<?php echo((!$color_track) ? '' : '2'); (!$color_track) ? $color_track = true : $color_track = false; ?>">
<td class="cell1"><?php echo(trim($this->convert_name($client))); ?></td>
<td class="cell2"><?php echo($client_stats[$client][0]); ?></td>
<td class="cell2"><?php echo($client_stats[$client][1]); ?></td>
<td class="cell2"><?php echo($client_stats[$client][2]); ?></td>
<td class="cell2"><?php echo($client_stats[$client][3]); ?></td>
<td class="cell2"><?php echo($client_stats[$client][4]); ?></td>
<td class="cell3"><?php echo($count); ?></td>
</tr>
<?php
}
?>
</table>
</td>
</tr>
<?php
}
}
}
private function query_safe($input) {
return (htmlentities(urlencode($input)));
}
private function error_table_row($error) {
?>
<tr class="error_message_block">
<td><?php echo(htmlentities($error->getMessage())); ?></td>
</tr>
<?php
}
private function no_support() {
if (isset($_COOKIE['xhtml_override'])) {
$this->display();
}
elseif (isset($this->runtime->externals['override_proceed'])) {
setcookie('xhtml_override', '1', time() + 3600, $_SERVER['PHP_SELF'], $this->env_variables['server_name'], false);
$this->display(true);
}
else {
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<meta name="robots" content="noindex,nofollow,noarchive">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title><?php echo(htmlentities('ERROR | '.settings::CACHE_NAME.' '.settings::CACHE_VERSION)); ?></title>
</head>
<body bgcolor="#CDCDCD">
<center><h2><font color="#FF0000">Please Upgrade Browser:</font></h2></center>
<hr>
<br>
<center><em>If you are receiving this message, then your browser does not support XHTML.</em></center>
<center><em>Click <a href="http://<?php echo(htmlentities($this->runtime->env_variables['url'])); ?>?override_proceed=1">here</a> to still proceed.</em></center>
<br>
<hr>
<p><b><font color="#FF0000">ERROR: </font></b>The HTTP Accept header signaling support for XHTML was not sent by your browser.<br>
<b><font color="#0000FF">Browser: </font></b><code><i><?php echo(htmlentities($this->runtime->env_variables['user_agent'])); ?></i></code></p>
</body>
</html>
<?php
}
}
private function check_xhtml_support() {
if (isset($_SERVER['HTTP_ACCEPT'])) {
//Seems that we must manually declare document as XHTML, otherwise some browsers will treat output as html.
if (stripos($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml') !== false) {
header('Content-Type: application/xhtml+xml; charset=utf-8');
return true;
}
}
return false;
}
private function display($override=false) {
echo('<?xml version="1.0" encoding="UTF-8"?>');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
<head>
<meta name="robots" content="noindex,nofollow,noarchive" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?php echo(htmlentities(settings::CACHE_NAME.' '.settings::CACHE_VERSION)); ?></title>
<style type="text/css">
<?php
//For proper XML, even the CSS must have xml entities escaped.
$CSS =
' body {
background-color: #FFFFFF;
font-family: "Times New Roman", "Palatino Linotype", "Book Antiqua", Palatino, serif, sans-serif, Arial, Helvetica;
}
#title, .table_net_cell, .table_top_cell, .no_list, #unknown_parameter, #back_to_main, #support_info, #network_tabs, .error_message_block td {
text-align: center;
}
.table_cell, .table_cell2, .bottom_rows {
text-align: left;
}
#title, .data_table {
margin: auto;
}
#title {
width: 95%;
background-color: #DEDEFF;
}
#title, #network_tabs span {
border-color: #FFCCCC;
border-width: thin;
border-style: solid;
}
#title:hover {
background-color: #D6D6F7;
}
a.title_text:link, a.title_text:visited, a.title_text:hover, a.title_text:active {
color: #FF8888;
}
.data_table {
border-color: #000000;
border-width: medium;
border-style: solid;
'.((strpos($this->runtime->env_variables['user_agent'], 'AppleWebKit') !== false) ? '' : 'min-').'width: 80%;
}
.table_net_cell {
background-color: #BABABA;
font-size: large;
}
.table_top_cell {
background-color: #CCCCCC;
}
.table_cell {
background-color: #DCDCDC;
}
.table_cell2 {
background-color: #EDEDED;
}
.table_cell:hover, .table_cell2:hover {
background-color: #EDEDFF;
}
.table_cell:hover td, .table_cell2:hover td {
color: #4A0000;
}
.table_cell td:hover, .table_cell2 td:hover {
color: #990000;
}
.cell1 {
padding-left: 5px;
padding-right: 15px;
}
.cell2 {
padding-left: 10px;
padding-right: 10px;
}
.cell3 {
padding-left: 5px;
padding-right: 5px;
}
.sub_table {
width: 100%;
border-collapse: collapse;
}
.bottom_rows {
background-color: #F1F1F1;
}
.no_list {
background-color: #FFFFFF;
}
#network_tabs {
margin-top: 15px;
margin-bottom: 15px;
margin-left: auto;
margin-right: auto;
padding: 0px;
}
#network_tabs span {
background-color: #FFEEEE;
vertical-align: middle;
padding: 5px;
color: #444444;
}
#network_tabs span:hover {
background-color: #FFE1E1;
color: #222222;
}
#network_tabs a:link, #network_tabs a:visited {
color: #4545FF;
}
#network_tabs a:hover, #network_tabs a:active {
color: #662200;
}
.shadow_text {
color: #989898;
}
a.table_address:link, a.table_address:visited {
color: #3333FF;
}
a.table_address:hover, a.table_address:active {
color: #FF3333;
}
#unknown_parameter, #support_info {
margin-top: 10px;
}
#support_info {
margin-bottom: 20px;
}
#back_to_main {
margin-top: 40px;
}
.cell_debug_head {
width: 150px;
padding-left: 5px;
padding-right: 15px;
}
#cell_debug tr td {
text-decoration: none;
}
#cell_debug tr:hover td {
text-decoration: underline;
}
#cell_debug tr td + td {
padding-right: 20px;
}
.green {
color: #33BB33;
}
.yellow {
color: #BBBB33;
}
.red {
color: #BB3333;
}
a.no_underline {
text-decoration: none;
}
abbr[title="current leaves"], abbr[title="uptime"] , abbr[title="maximum leaves"], .error_message_block td, .table_net_cell, #unknown_parameter {
font-weight: bold;
}
.error_message_block td {
background-color: #CC0000;
color: #000000;
}
.error_message_block td:hover {
background-color: #DD6666;
color: #703000;
}
';
echo((isset($_COOKIE['xhtml_override']) || $override) ? "\t\t\t<!--\r\n".$CSS."\t\t\t-->\r\n" : htmlentities($CSS));
?>
</style>
</head>
<body>
<table id="title">
<tr>
<td>
<a href="http://sourceforge.net/projects/beaconcache/" class="title_text"><?php echo(htmlentities(settings::CACHE_NAME.' '.settings::CACHE_VERSION)); ?></a>
</td>
</tr>
</table>
<div id="network_tabs"><span> Networks: [
<?php
foreach ($this->runtime->settings->NETWORKS as $network) {
?>
<a href="<?php echo('http://'.$this->runtime->env_variables['url']); ?>?display=<?php echo($this->query_safe($network)); ?>"><?php echo(htmlentities($network)); ?></a>
<?php
}
?>
]</span></div>
<?php
if (isset($this->runtime->externals['display'])) {
if (in_array($this->runtime->externals['display'], $this->runtime->settings->NETWORKS)) {
$this->network = $this->runtime->externals['display'];
$html_safe_network = htmlentities($this->runtime->externals['display']); //If, for what ever reason, the network name is irregular, it will be parsed right in html by html safe-encoding it...
$color_track = false;
?>
<table class="data_table">
<tr>
<td class="table_net_cell"><?php echo($html_safe_network); ?></td>
</tr>
<?php
if (isset($_POST['cache_submit']) && settings::WEBFRONT_URL_ADDS) {
try {
$this->url_add($color_track, $this->runtime->strip_chars($_POST['cache_submit'], true));
}
catch (Exception $error) {
$this->error_table_row($error);
}
}
elseif (isset($this->runtime->externals['query']) && settings::CHECKS_ALLOWED) {
try {
$this->check_url($color_track, $this->runtime->externals['query']);
}
catch (Exception $error) {
$this->error_table_row($error);
}
}
else {
try {
$this->grab_hosts($color_track); //Execute the hosts output.
}
catch (Exception $error) {
$this->error_table_row($error);
}
try {
$this->grab_urls($color_track); //Execute the URLs output.
}
catch (Exception $error) {
$this->error_table_row($error);
}
if (settings::WEBFRONT_URL_ADDS) {
?>
<tr>
<td>
<table class="sub_table">
<tr class="bottom_rows">
<td class="cell1">
Add a <?php echo($html_safe_network); ?> URL:
</td>
<td class="cell2">
<form method="post" action="<?php echo('http://'.$this->runtime->env_variables['url'].'?display='.$this->query_safe($this->runtime->externals['display'])); ?>">
<div>
<input name="cache_submit" type="text" />
<input type="submit" value="Add" />
</div>
</form>
</td>
</tr>
</table>
</td>
</tr>
<?php
}
try {
$this->client_stats($color_track, $this->network); //Execute the client table....
}
catch (Exception $error) {
$this->error_table_row($error);
}
try {
if (settings::ENABLE_HIT_STATS) {
$stats_get = new data_manage($this, 'down', 'stats_total_requests', $this->network);
$stat_total_requests = (int)((!empty($stats_get->data->contents)) ? $stats_get->data->contents[0] : 0);
$stats_get = new data_manage($this, 'down', 'stats_total_updates', $this->network);
$stat_total_updates = (int)((!empty($stats_get->data->contents)) ? $stats_get->data->contents[0] : 0);
$stats_get = new data_manage($this, 'down', 'stats_requests', $this->network);
$stat_requests_rate = (int)((!empty($stats_get->data->contents)) ? count($stats_get->data->contents) : 0);
$stats_get = new data_manage($this, 'down', 'stats_updates', $this->network);
$stat_updates_rate = (int)((!empty($stats_get->data->contents)) ? count($stats_get->data->contents) : 0);
?>
<tr>
<td>
<table class="sub_table">
<tr class="bottom_rows">
<td class="cell1">Total Hits: <?php echo($stat_total_requests + $stat_total_updates); ?></td>
<td class="cell2">Hits per hour: <?php echo($stat_requests_rate + $stat_updates_rate); ?></td>
<td class="cell2">Total Requests: <?php echo($stat_total_requests); ?></td>
<td class="cell2">Total Updates: <?php echo($stat_total_updates); ?></td>
<td class="cell2">Requests per hour: <?php echo($stat_requests_rate); ?></td>
<td class="cell3">Updates per hour: <?php echo($stat_updates_rate); ?></td>
</tr>
</table>
</td>
</tr>
<?php
}
}
catch (Exception $error) {
$this->error_table_row($error);
}
}
?>
</table>
<div id="back_to_main">[ <a href="<?php echo('http://'.$this->runtime->env_variables['url']); ?>" class="table_address">Main</a> ]</div>
<?php
try {
$update_retry = new update($this->runtime, 'retry', $this->network);
}
catch (Exception $error) {}
}
else {
?>
<div id="unknown_parameter">Unknown parameter given.</div>
<?php
}
}
else {
?>
<div id="support_info">This web cache supports: <?php echo(htmlentities(implode(', ', $this->runtime->settings->NETWORKS))); ?></div>
<?php
if (settings::ENABLE_HIT_STATS || settings::ENABLE_CLIENT_STATS) {
?>
<table class="data_table">
<?php
try {
if (settings::ENABLE_HIT_STATS) {
$stat_total_requests = $stat_total_updates = $stat_requests_rate = $stat_updates_rate = 0;
foreach ($this->runtime->settings->NETWORKS as $temp_net) {
$stats_get = new data_manage($this, 'down', 'stats_total_requests', $temp_net);
$stat_total_requests += (int)((!empty($stats_get->data->contents)) ? $stats_get->data->contents[0] : 0);
$stats_get = new data_manage($this, 'down', 'stats_total_updates', $temp_net);
$stat_total_updates += (int)((!empty($stats_get->data->contents)) ? $stats_get->data->contents[0] : 0);
$stats_get = new data_manage($this, 'down', 'stats_requests', $temp_net);
$stat_requests_rate += (int)((!empty($stats_get->data->contents)) ? count($stats_get->data->contents) : 0);
$stats_get = new data_manage($this, 'down', 'stats_updates', $temp_net);
$stat_updates_rate += (int)((!empty($stats_get->data->contents)) ? count($stats_get->data->contents) : 0);
}
?>
<tr>
<td class="table_top_cell">
Full Statistics:
</td>
</tr>
<tr>
<td>
<table class="sub_table">
<tr class="bottom_rows">
<td class="cell1">Total Hits: <?php echo($stat_total_requests + $stat_total_updates); ?></td>
<td class="cell2">Hits per hour: <?php echo($stat_requests_rate + $stat_updates_rate); ?></td>
<td class="cell2">Total Requests: <?php echo($stat_total_requests); ?></td>
<td class="cell2">Total Updates: <?php echo($stat_total_updates); ?></td>
<td class="cell2">Requests per hour: <?php echo($stat_requests_rate); ?></td>
<td class="cell3">Updates per hour: <?php echo($stat_updates_rate); ?></td>
</tr>
</table>
</td>
</tr>
<?php
}
}
catch (Exception $error) {
$this->error_table_row($error);
}
try {
$this->client_stats($color_track); //Execute the client table...
}
catch (Exception $error) {
$this->error_table_row($error);
}
?>
</table>
<?php
}
}
?>
</body>
</html>
<?php
}
}
$main = new gwc();
?>