Location: PHPKode > projects > PHPMyServer > lite/includes/functions.php4.php
<?PHP
//
// PHPMyServer - A PHP System Information Script - Old project name was PHPMyStats
// http://www.phpmyserver.com/
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// $Id: index.php/index.php4.php/index.php5.php/etc ,v 2.6 13-08-2005 16:30 precision Exp $
//
// Date in $Id is as DD-MM-YY

//PHPMyServer - Lite Client v2.6
//Build version:
//  split version at the DOT, before the DOT is the CORE version, AFTER the DOT is de RELEASE
//Every new release will get an higher number, so when i released version 2 of the script for the 126523st time, its version v2.126523

//Copyright 2004-2005 by KingOfDos Intra/Extra/Internet WebServices
//http://www.phpmyserver.com
//http://www.kingofdos.com




function &last(&$array) {
	if (!count($array)) return null;
	end($array);
	return $array[key($array)];
}

//------------------------- XML Functions
//XML Function designed by "gleber" _A~T "mapnet" d~0_t "pl", posted at  27-Mar-2005 12:03
//See also: http://php.net/xml_parse_into_struct
//It's an XML parser that i (KingOfDos) always use to get XML data in PHP, works fine for me ;)
//Also made some changes (debugging for error_reporting(E_ALL))
function myParseXML(&$vals, &$dom, &$lev) {
	do {
	$curr = current($vals);
	$lev = $curr['level'];
       switch ($curr['type']) {
           case 'open':
               if (isset($dom[$curr['tag']])) {
                   $tmp = $dom[$curr['tag']];
                   if (!isset($tmp['__multi']))
                       $dom[$curr['tag']] = array('__multi' => true, $tmp);
                   array_push($dom[$curr['tag']], array());
                   $new =& last($dom[$curr['tag']]);
               } else {
                   $dom[$curr['tag']] = array();
                   $new =& $dom[$curr['tag']];
               }
               next($vals);
               myParseXML($vals, $new, $lev); // 2.6, removed the & before $vals (myParseXML(&$vals, $new, $lev))
               break;
           case 'cdata':
               break;
           case 'complete':
               if (!isset($dom[$curr['tag']]) AND isset($curr['value']))
                   $dom[$curr['tag']] = $curr['value'];
               elseif (isset($curr['value'])) {
                   if (is_array($dom[$curr['tag']]))
                       array_push($dom[$curr['tag']] , $curr['value']);
                   else
                       array_push($dom[$curr['tag']] = array($dom[$curr['tag']]) , $curr['value']);
               } else
			   		return false;
               break;
           case 'close':
               return;
       }
   }
   while (next($vals)!==FALSE);
}

function MyXMLtoArray($XML) {
       $xml_parser = xml_parser_create();
       xml_parse_into_struct($xml_parser, $XML, $vals);
       xml_parser_free($xml_parser);
       reset($vals);
       $dom = array(); $lev = 0;
       myParseXML($vals, $dom, $lev);
       return $dom;
}




//----------Update function Checker
//Update note's / system:
//     - The update is ONLY a check, I / PHPMyServer wil NOT automaticly update anything.
//     - The Client (Lite Client / Pro Client) will open an URL every week, with the MD5 hash from your
//       index.php file. By that MD5 hash you will get any result like:
//           - md5_unknown            Your MD5 string is unknown by the PHPMyServer update system
//           - ud2_v2.x               The latest version when your not up2date (x will contain the sub version of PHPMyServer v2.x)
//           -                        PHPMyServer Update System will return nothing when your configuration is up2date
//
//Update rule's:
//     - You have an maximum of 1 update check every 5 days, when the update is available you get the information showed above.
//     - When you get the update information more ofthen than 1 time a 5 day's your IP adres will be blocked for 2 weeks (PHPMyServer still working fine, but no automaticly update system).
function PMSUpdateExec($pms_update_basic_url,$md5_array) {
	$update_after_x = (60*60*24*3)+1; //DON'T CHANGE THIS, IF YOUR SCRIPT REQUESTS THE SAME MD5 STRING AGAIN (from this IP) WITHIN 3 DAY'S I'LL BLOCK YOU FOREVER FROM THE UPDATE SYSTEM!!!!!!	
	//$update_after_x = 60; //ONLY FOR DEVELOPMENT AT MY OWN SERVER, HE HAS THE BLOCK FUNCTION @ DISABLED
	
	if (!is_array($md5_array))
		return 'Update System - Expected an MD5 array.';
	
	//Read Update Dir
	$dir = getcwd().DIRECTORY_SEPARATOR.'update'.DIRECTORY_SEPARATOR;
	
	$tree = array();
	$dir_handle  = opendir($dir);
	while (false !== ($filename = readdir($dir_handle))) {
		if ($filename != '.' AND $filename != '..')
			$tree[] = $filename;
	}
	if (count($tree)>=1)
		sort($tree);
	
	//Loop itself
	$ret_data_arr = array(); //Create the return array
	foreach($md5_array as $product_key => $product_md5) {
		$update_filename = $dir.'/pms_update_'.$product_md5.'.tmp';
		
		if (file_exists($update_filename) AND is_readable($update_filename) AND filesize($update_filename)>=1) {
			if ($filehand = fopen($update_filename,'r') AND $data = fread($filehand,filesize($update_filename))) {
				
				//print_r($data_expl);
				if(ereg('\|\|s\|\|',$data) AND $data_expl = explode('||s||',$data) AND count($data_expl)==5 AND is_numeric($data_expl[0])) {
					if ($data_expl[0]<=time()-$update_after_x) {//Update allowed
						//echo 'you may update now';
						fclose($filehand);
						
						if ($update_arr = PMSUpdateSystem($pms_update_basic_url.$product_md5) AND match_secure($update_arr['prog_name']) AND match_secure($update_arr['prog_version']) AND match_secure($update_arr['prog_reldate']) AND match_secure($update_arr['prog_url'])) {
							if ($updatehand = fopen($update_filename,'w') AND fwrite($updatehand,time().'||s||'.$update_arr['prog_name'].'||s||'.$update_arr['prog_version'].'||s||'.$update_arr['prog_reldate'].'||s||'.$update_arr['prog_url'])) {
								//echo 'updated dinges';
								fclose($updatehand);
							}
						}
					}
					
					if (match_secure($data_expl[1]) AND match_secure($data_expl[2]) AND match_secure($data_expl[4])) //All chars accepted? So no strange chars come true (like HTML). Only an extra security
						$ret_data_arr[] = array('product'=>$data_expl[1],'version'=>$data_expl[2],'url'=>$data_expl[4]);
					else
						return 'Update System - Sended data from Update Server has some illegal chars. Due security reasons the script automaticly blocks this update.';
				} elseif (is_numeric($data)) {
					if ($data<=time()-$update_after_x) {//Update allowed
						//echo 'you may update now';
						fclose($filehand);
						$updatehand = fopen($update_filename,'w');
						if ($update_arr = PMSUpdateSystem($pms_update_basic_url.$product_md5) AND match_secure($update_arr['prog_name']) AND match_secure($update_arr['prog_version']) AND match_secure($update_arr['prog_reldate']) AND match_secure($update_arr['prog_url']))
							fwrite($updatehand,time().'||s||'.$update_arr['prog_name'].'||s||'.$update_arr['prog_version'].'||s||'.$update_arr['prog_reldate'].'||s||'.$update_arr['prog_url']);
						else
							fwrite($updatehand,time());
						fclose($updatehand);
					}
				}
			} else {
				return 'Update System - Can\'t read file ['.$update_filename.']';
			}
		} elseif ($filehand = fopen($update_filename,'a')) { //If there is an update available
			//echo $pms_update_basic_url.$product_md5.'<br>';
			if ($update_arr = PMSUpdateSystem($pms_update_basic_url.$product_md5)) { //If we can write to the file (create when not exist)
				if (match_secure($update_arr['prog_name']) AND match_secure($update_arr['prog_version']) AND match_secure($update_arr['prog_reldate']) AND match_secure($update_arr['prog_url'])){
					//print_r($update_arr);
					fwrite($filehand,time().'||s||'.$update_arr['prog_name'].'||s||'.$update_arr['prog_version'].'||s||'.$update_arr['prog_reldate'].'||s||'.$update_arr['prog_url']);
					$ret_data_arr[] = array('product'=>$update_arr['prog_name'],'version'=>$update_arr['prog_version'],'url'=>$update_arr['prog_url']);
				}
			} else {
				fwrite($filehand,time());
			}
			fclose($filehand);
		} else {
			return 'Update System - Can\'t create file ['.$update_filename.']';
		}
	}
	if (count($ret_data_arr)>0)
		return $ret_data_arr;
	else
		return false;
	
}

function PMSUpdateSystem($pms_update_url) {
	
	//Opening connection
	if ($str = http_get($pms_update_url)) {
		$str_expl = explode('|||',$str); //explode readed data
		
		if (isset($str_expl) AND isset($str_expl[0]) AND isset($str_expl[1]) AND isset($str_expl[2]) AND isset($str_expl[3])) {
			return array(
				'prog_name'=>$str_expl[0], //Script name
				'prog_version'=>$str_expl[1], //Release version
				'prog_reldate'=>$str_expl[2], //Release date as timestamp
				'prog_url'=>$str_expl[3] //The url of the release/whatever
			);
		} else {
			//echo 'updatesystem_error_1'."\r\n\r\n\r\n";print_r($str_expl);
			return false;
		}
	} else {
		//echo 'updatesystem_error_2';
		return false;
	}
}





function match_secure($txt) {
	$match = "/^[\w\d\. :_\\\\\\/\?-]+$/i";
	
	if (is_array($txt))
		foreach ($txt as $val)
			if (!preg_match($match,$txt))
				return false;
	
	if (preg_match($match,$txt)) //only allow: a-zA-Z0-9._\/?-
		return true;
	else
		return false;
}

//IP Security match
function match_secure_ipv4($ip){
	return preg_match("/\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]\.\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]\.\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]\.\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]/x",$ip);
}


//Monster Magnet - Powertrip - 06 - Baby Götterdämerung
//HTTP File Get
if (!function_exists('http_get')) {
	function http_get($url) {
		if (!match_secure($url)){//Security check
			return false;
		}
		
		//If someone knows a better way to do this, please tell me :)
		//I specialy DON'T use the fopen method to external files, couse that can create some problems. So i think this is a better way to do it :)
		if (!$url_data = parse_url($url))
			return false;
		
		$port = isset($url_data['port']) ? $url_data['port'] : 80;
		if (!gethostbyname($url_data['host'])!==false OR !$http_pointer = fsockopen($url_data['host'], $port,$t_errorno,$t_errorstr,5))
			return false;

		$query = 'GET '.$url_data['path']." HTTP/1.0\n";
		$query .= 'Host: '.$url_data['host'];
		$query .= "\n\n";
		fwrite($http_pointer, $query);
		$buffer = '';
		while ($tmp = fread($http_pointer, 1024)) {
			$buffer .= $tmp;
		}
		//Clear the \r, explode on \n
		//Disabled this two rules for version v2.6.
		//when he has an content-length he will crash (becose he can't find the \r's) and then the substr fails
		if (ereg("\n",$buffer) AND ereg("\r",$buffer))//If the webserver sends an \r AND an \n, remove the \r so the script can explode on \n.
			$buffer_new = str_replace("\r","",$buffer);
		$buffer_rules = explode("\n",$buffer_new);

		if (preg_match('/HTTP[0-9].[0-9]+ 404/',$buffer))//eregi('http1/(\w) 404',$buffer_rules[0]) AND 
			return false;
			
		
		if (eregi('content-length',$buffer) AND preg_match('/Content-Length: ([0-9]+)/', $buffer, $parts)) { //If there is an content-length, use it to select the start of the data.
			return substr($buffer, - $parts[1]); //This is the best way, but not all webservers / scripts return this value, so there MUST be a fallback.
		} else {//Fallback method
			//Search the last header.
			//Normaly all the headers are directly after eachother, so the script search for the first empty rule.
			$buffer = $buffer_new;
			$header_end = 0;
			foreach($buffer_rules as $buffer_key => $buffer_val) {
				if (isset($buffer_rules[$buffer_key]) AND !empty($buffer_rules[$buffer_key]))
					$header_end++;
				else
					break;
			}
			$header_end++;//Add 1 at the header_end counter. Then you "shoud" have the first content rule.
			//Create new return to the script
			$return_data = '';
			for($add_cnt=$header_end;$add_cnt<=count($buffer_rules)-1;$add_cnt++) { //Loop from the first data.
				$return_data .= $buffer_rules[$add_cnt]."\n";
			}
			return $return_data;
		}
	}
}
?>
Return current item: PHPMyServer