首页
社区
课程
招聘
[旧帖] [求助] 外国人写的PHP 注册系统。源程序版 0.00雪花
发表于: 2008-8-5 23:26 4649

[旧帖] [求助] 外国人写的PHP 注册系统。源程序版 0.00雪花

2008-8-5 23:26
4649
程序如下

ConfigurationFile.class.php
<?php

///////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 Point Clark Networks.
//
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////

/**
 * Configuration file handling class.
 *
 * @package Api
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

///////////////////////////////////////////////////////////////////////////////
// D E P E N D E N C E S
///////////////////////////////////////////////////////////////////////////////

require_once("File.class.php");

///////////////////////////////////////////////////////////////////////////////
// E X C E P T I O N  C L A S S E S
///////////////////////////////////////////////////////////////////////////////

/**
 * Configuration file exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class ConfigurationFileException extends EngineException
{
	/**
	 * ConfigurationFileException constructor.
	 *
	 * @param string $filename name of the file
	 * @param int $linenumber linenumber where the error occurred
	 * @param int $code error code
	 */

	public function __construct($filename, $linenumber, $code)
	{
		parent::__construct(LOCALE_LANG_ERRMSG_PARSE_ERROR.": ".basename($filename)."($linenumber)", $code);
	}
}

///////////////////////////////////////////////////////////////////////////////
// C L A S S
///////////////////////////////////////////////////////////////////////////////

/**
 * Configuration file handling class.
 *
 * A generic configuration file parser.
 *
 * @package Api
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class ConfigurationFile extends File
{
	///////////////////////////////////////////////////////////////////////////////
	// F I E L D S
	///////////////////////////////////////////////////////////////////////////////

	protected $method = 'explode';
	protected $token = '=';
	protected $limit = 2;
	protected $flags = null;
	protected $loaded = false;
	protected $cfg = array();

	///////////////////////////////////////////////////////////////////////////////
	// M E T H O D S
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * Configuration file constructor.
	 *
	 * Valid method enumerators are:
	 * - ini: parses a samba style ini file
	 * - match:  use preg_match, requires a valid regex expression as the "token" parameter
	 * - split:  use preg_split, requires a valid regex expression as the "token" parameter
	 * - explode: (default) requires a delimiter as the "token" parameter
	 *
	 * @param string $filename target file
	 * @param string $method configuration file type (default = explode)
	 * @param string $token a valid regex or delimiter
	 * @param int $limit (optional) max number of parts, the first part is always used as the "key"
	 * @param int $flags (optional) preg_match/preg_split accept various flags (cf. @link http://www.php.net )
	 */

	public function __construct($filename, $method = 'explode', $token = '=', $limit = 2, $flags = null)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__construct($filename, true);

		switch ($method) {

		case 'ini':
			$token = array('/^\s*\[(.*?)\]\s*$/', '=');
			break;

		case 'split':

			if (strlen($token) == 1) {
				$method = 'explode';
				break;
			}

		case 'match':

			if (substr($token,0,1) != '/') {
				$token = "/".$token;
			}

			if (substr($token,-1,1) != '/') {
				$token .= "/";
			}
		}

		$this->method = $method;
		$this->token = $token;
		$this->limit = $limit;
		$this->flags = $flags;
		$this->loaded = false;
	}

	/**
	 * Loads a configuration file and returns its values as an array
	 *
	 * @param boolean $reload (optional) if true, a "fresh" copy will be retrieved rather than a cached version
	 * @return array parsed array of elements from configuration file
	 * @throws FileNotFoundException Exception (inherited from GetContentsAsArray)
	 * @throws FileIoException
	 */

	public function Load($reload=false)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if ($reload)
			$this->loaded = false;

		if (! $this->loaded) {
			try {
				$lines = $this->GetContentsAsArray();
			} catch (Exception $e) {
				throw $e;
			}

			$configfile = array();
			$n = 0;
			$match = "";

			switch ($this->method) {

			case 'ini':
				$key = null;
				foreach($lines as $line) {
					$n++;

					if (preg_match('/^\/\//', $line))
						continue;

					if (preg_match('/^#.*$/', $line)) {
						continue;
					} elseif (preg_match('/^\s*$/', $line)) {
						// a blank line
						continue;
					} elseif (preg_match($this->token[0], $line, $match)) {
						$key = $match[1];
					} elseif ((strpos($line,$this->token[1]) !== false) && (!(is_null($key)))) {
						$match = array_map('trim',explode($this->token[1],$line));
						$configfile[$key][$match[0]] = $match[1];
					} else {
						throw new ConfigurationFileException($this->filename, $n, COMMON_NOTICE);
					}
				}

				break;

			case 'match':
				foreach ($lines as $line) {
					$n++;

					if (preg_match('/^\/\/.*$/', $line))
						continue;

					if (preg_match('/^\#.*$/', $line)) {
						continue;
					} elseif (preg_match('/^\s*$/', $line)) {
						// a blank line
						continue;
					} elseif (preg_match($this->token, $line, $match, $this->flags)) {
						$configfile[$match[1]] = $match[2];
					} else {
						throw new ConfigurationFileException($this->filename, $n, COMMON_ERROR);
					}
				}

				break;

			case 'split':
				foreach ($lines as $line) {
					$n++;

					if (preg_match('/^\/\/.*$/', $line))
						continue;

					if (preg_match('/^\#.*$/', $line)) {
						continue;
					} elseif (preg_match('/^\s*$/', $line)) {
						// a blank line
						continue;
					} else {
						$match = array_map('trim',preg_split($this->token,$line,$this->limit,$this->flags));

						if (($match[0] == $line)||(empty($match[0]))) {
							throw new ConfigurationFileException($this->filename, $n, COMMON_ERROR);
						} else {
							if ($this->limit == 2) {
								$configfile[$match[0]] = $match[1];
							} else {
								$configfile[$match[0]] = array_slice($match,1);
							}
						}
					}
				}

				break;

			default:
				foreach ($lines as $line) {
					$n++;

					if (preg_match('/^\/\/.*$/', $line))
						continue;

					if (preg_match('/^\#.*$/', $line)) {
						continue;
					} elseif (preg_match('/^\s*$/', $line)) {
						// a blank line
						continue;
					} else {
						$match = array_map('trim',explode($this->token,$line,$this->limit));

						if ($match[0] == $line) {
							throw new ConfigurationFileException($this->filename, $n, COMMON_ERROR);
						} else {
							if ($this->limit == 2) {
								$configfile[$match[0]] = $match[1];
							} else {
								$configfile[$match[0]] = array_slice($match,1);
							}
						}
					}
				}
			}

			$this->cfg = $configfile;
			$this->loaded = true;
		}

		return $this->cfg;
	}

	/**
	 * @access private
	 */

	public function __destruct()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__destruct();
	}
}

// vim: syntax=php ts=4
?>


==========================================================
Engine.class.php

<?php

///////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 Point Clark Networks.
//
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////

/**
 * Base class for the API.
 *
 * @package Api
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

///////////////////////////////////////////////////////////////////////////////
// D E P E N D E N C I E S
///////////////////////////////////////////////////////////////////////////////

require_once(dirname(__FILE__) . '/../common/Globals.inc.php');
require_once(dirname(__FILE__) . '/../common/Logger.class.php');
require_once(dirname(__FILE__) . '/../common/Error.class.php');

///////////////////////////////////////////////////////////////////////////////
// E X C E P T I O N  C L A S S E S
///////////////////////////////////////////////////////////////////////////////

/**
 * Base exception for all exceptions in the API.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class EngineException extends Exception
{
	/**
	 * EngineException constructor.
	 *
	 * Unlike a core PHP exception, the message and code parameters are required.
	 *
	 * - COMMON_DEBUG - debug message
	 * - COMMON_VALIDATION - validation error message
	 * - COMMON_INFO - informational message (e.g. dynamic DNS updated with IP w.x.y.z)
	 * - COMMON_NOTICE - pedantic warnings (e.g. dynamic DNS updated with IP w.x.y.z)
	 * - COMMON_WARNING - normal but significant errors (e.g. dynamic DNS could not detect WAN IP)
	 * - COMMON_ERROR - errors that should not happen under normal circumstances
	 * - COMMON_FATAL - really nasty errors
	 *
	 * @param string $message error message
	 * @param integer $code error code
	 * @return void
	 */

	public function __construct($message, $code)
	{
		parent::__construct($message, $code);

		if ($code >= COMMON_WARNING)
			Logger::LogException($this, true);
	}
}

/**
 * Validation exception for API.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class ValidationException extends EngineException
{
	/**
	 * ValidationException constructor.
	 *
	 * @param string $message error message
	 * @return void
	 */

	public function __construct($message)
	{
		parent::__construct($message, COMMON_VALIDATION);
	}
}

/**
 * Custom configuration discovered exception.
 *
 * In some instances, it may be impossible to manage a configuration file if
 * it has been customized.  For instance, the Amavis configuration file uses
 * regular expressions in the banned_filename_re parameter.  These regular
 * expressions are flexible, but are impossible to decipher without showing
 * the end user some not-so-user-friendly details.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class CustomConfigurationException extends EngineException
{
	/**
	 * Custom configuration constructor.
	 *
	 * @param string $file file name
	 * @return void
	 */

	public function __construct($file)
	{
		parent::__construct("Custom configuration discovered" . " - " . $file, COMMON_NOTICE);
	}
}

/**
 * Duplicate entry exception for API.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class DuplicateException extends EngineException
{
	/**
	 * DuplicateException constructor.
	 *
	 * @param string $message error message
	 * @return void
	 */

	public function __construct($message)
	{
		parent::__construct($message, COMMON_WARNING);
	}
}

/**
 * Security violation exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2007, Point Clark Networks
 */

class SecurityViolationException extends EngineException
{
	/**
	 * SecurityViolationException constructor.
	 *
	 * @return void
	 */

	public function __construct()
	{
		parent::__construct("Security violation", COMMON_ERROR);
	}
}

/**
 * SQL exception for API.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class SqlException extends EngineException
{
	/**
	 * SqlException constructor.
	 *
	 * @param string $message error message
	 * @return void
	 */

	public function __construct($message)
	{
		parent::__construct($message, COMMON_WARNING);
	}
}

///////////////////////////////////////////////////////////////////////////////
// C L A S S
///////////////////////////////////////////////////////////////////////////////

/**
 * Base class for the API.
 *
 * @package Api
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class Engine
{
	///////////////////////////////////////////////////////////////////////////////
	// F I E L D S
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * @var array validation error queue
	 */

	protected $errors = array();

	///////////////////////////////////////////////////////////////////////////////
	// M E T H O D S
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * Engine constructor.
	 *
	 * @return void
	 */

	function __construct()
	{
		if (! file_exists("/etc/system/nosecurity")) {
			$user = get_current_user();

			if (!(($user == "root") || ($user == "webconfig")))
				throw new SecurityViolationException();
		}

		require_once(GlobalGetLanguageTemplate(preg_replace("/Engine/", "Locale",__FILE__)));
	}

	/**
	 * Prints a message to the log.
	 *
	 * The following log levels are used:
	 *
	 * - COMMON_DEBUG - debug messages
	 * - COMMON_VALIDATION - validation error message
	 * - COMMON_INFO - informational messages (e.g. dynamic DNS updated with IP w.x.y.z)
	 * - COMMON_NOTICE - pedantic warnings (e.g. dynamic DNS updated with IP w.x.y.z)
	 * - COMMON_WARNING - normal but significant errors (e.g. dynamic DNS could not detect WAN IP)
	 * - COMMON_ERROR - errors that should not happen under normal circumstances
	 * - COMMON_FATAL - really nasty errors
	 *
	 * @param  int  $code  error code
	 * @param  string  $message  short and informative message
	 * @param  string  $tag  identifier (usually the method)
	 * @param  int  $line  line number
	 * @return  void
	 * @static
	 */

	static function Log($code, $message, $tag, $line)
	{
		$error = new Error($code, $message, $tag, $line, null, true);
		Logger::Log($error);
	}

	///////////////////////////////////////////////////////////////////////////////
	// E R R O R  H A N D L I N G
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * Add a validation error to the queue.
	 *
	 * @param string $message error message
	 * @param string $tag tag (usually the method call)
	 * @param integer $line line number
	 * @return void
	 */

	protected function AddValidationError($message, $tag, $line)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$error = new Error(COMMON_VALIDATION, $message, $tag, $line, null, Error::TYPE_ERROR, true);
		$this->errors[] = $error;

		if (COMMON_DEBUG_MODE)
			Logger::Log($error);
	}

	/**
	 * Returns an array of validation error messages.
	 *
	 * @param boolean $purge  (optional) if true, the error queue will be purged.
	 * @return array validation errors
	 */

	public function GetValidationErrors($purge = false)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$error_messages = array();

		foreach ($this->errors as $error)
			$error_messages[] = $error->GetMessage();

		if ($purge)
			$this->errors = array();

		return $error_messages;
	}

	/**
	 * Returns an array of validation error objects.
	 *
	 * @param boolean $purge  (optional) if true, the error queue will be purged.
	 * @return array validation errors
	 */

	public function CopyValidationErrors($purge = false)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$errors_copy = $this->errors;

		if ($purge)
			$this->errors = array();

		return $errors_copy;
	}

	/**
	 * Returns true if validation errors exist.
	 *
	 * @return boolean true if validation errors exist
	 */

	public function CheckValidationErrors()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (empty($this->errors))
			return false;
		else
			return true;
	}

	/**
	 * @access private
	 */

	public function __destruct()
	{
		// A bit noisy
		// if (COMMON_DEBUG_MODE)
		//	$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);
	}
}

// vim: syntax=php ts=4
?>


==========================================================
File.class.php

<?php

///////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 Point Clark Networks.
//
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////

/**
 * File manipulation class.
 *
 * @package Api
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

///////////////////////////////////////////////////////////////////////////////
// D E P E N D E N C E S
///////////////////////////////////////////////////////////////////////////////

require_once("Engine.class.php");
require_once("ShellExec.class.php");

///////////////////////////////////////////////////////////////////////////////
// E X C E P T I O N  C L A S S E S
///////////////////////////////////////////////////////////////////////////////

/**
 * File exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class FileException extends EngineException
{
	/**
	 * FileException constructor.
	 *
	 * @param string $errmsg error message
	 * @param int $code error code
	 */

	public function __construct($errmsg, $code)
	{
		parent::__construct($errmsg, $code);
	}
}

/**
 * File permissions exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class FilePermissionsException extends EngineException
{
	/**
	 * FilePermissionsException constructor.
	 *
	 * @param string $errmsg error message
	 * @param int $code error code
	 */

	public function __construct($errmsg, $code)
	{
		parent::__construct($errmsg, $code);
	}
}

/**
 * File already exists exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class FileAlreadyExistsException extends EngineException
{
	/**
	 * FileAlreadyExistsException constructor.
	 *
	 * @param string $filename filename
	 * @param int $code error code
	 */

	public function __construct($filename, $code)
	{
		parent::__construct(FILE_LANG_ERRMSG_EXISTS . " - " . $filename, $code);
	}
}

/**
 * File not found exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class FileNotFoundException extends EngineException
{
	/**
	 * FileNotFoundException constructor.
	 *
	 * @param string $filename filename
	 * @param int $code error code
	 */

	public function __construct($filename, $code)
	{
		parent::__construct(FILE_LANG_ERRMSG_NOTEXIST . " - " . $filename, $code);
	}
}

/**
 * File I/O exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class FileIoException extends EngineException
{
	/**
	 * FileIoException constructor.
	 *
	 * @param string $filename filename
	 * @param int $code error code
	 */

	public function __construct($filename, $code)
	{
		parent::__construct(FILE_LANG_ERRMSG_READ . " - " . $filename, $code);
	}
}

/**
 * Value not found in file exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class FileNoMatchException extends EngineException
{
	/**
	 * FileNoMatchException constructor.
	 *
	 * @param string $filename filename
	 * @param int $code error code
	 * @param string $key key used to match a string
	 */

	public function __construct($filename, $code, $key)
	{
		parent::__construct(FILE_LANG_ERRMSG_NO_MATCH . " - $filename for key $key", $code);
	}
}

///////////////////////////////////////////////////////////////////////////////
// C L A S S
///////////////////////////////////////////////////////////////////////////////

/**
 * File handling class.
 *
 * The File class can be use for creating, reading and manipulating the
 * contents of a file.  If you need to change a configuration file, this may
 * be the class for you.  However, configuration files come in many different
 * forms, so this might not have what you need.  Feel free to do your own file
 * parsing.
 *
 * @package Api
 * @author Point Clark Networks
 * @license GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class File extends Engine
{
	///////////////////////////////////////////////////////////////////////////////
	// F I E L D S
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * @var string filename
	 */

	protected $filename = null;

	/**
	 * @var superuser superuser
	 */

	protected $superuser = false;

	/**
	 * @var boolean temporary Temporary file
	 */

	protected $temporary = false;

	/**
	 * @var boolean contents loaded flag
	 */

	protected $contents = null;

	const CMD_RM = '/bin/rm';
	const CMD_CAT = '/bin/cat';
	const CMD_MOVE = '/bin/mv';
	const CMD_COPY = '/bin/cp';
	const CMD_TOUCH = '/bin/touch';
	const CMD_CHOWN = '/bin/chown';
	const CMD_CHMOD = '/bin/chmod';
	const CMD_LS = '/bin/ls';
	const CMD_MD5 = '/usr/bin/md5sum';
	const CMD_FILE = '/usr/bin/file';
	const CMD_HEAD = '/usr/bin/head';
	const CMD_REPLACE = '/usr/sbin/cc-rename';

	///////////////////////////////////////////////////////////////////////////////
	// M E T H O D S
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * File constructor.
	 *
	 * @param string filename target file
	 * @param boolean $superuser superuser access required to read the file
	 * @param boolean $temporary create a temporary file
	 */

	public function __construct($filename, $superuser = false, $temporary = false)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if ($temporary) {
			$this->temporary = $temporary;
			$this->filename = tempnam(COMMON_TEMP_DIR, basename($filename));
		} else 
			$this->filename = $filename;

		$this->superuser = $superuser;

		parent::__construct();

		require_once(GlobalGetLanguageTemplate(__FILE__));
	}

	/**
	 * Returns the filename.
	 *
	 * @return string name of file
	 */
	function GetFilename()
	{
		return $this->filename;
	}

	/**
	 * Returns the contents of a file.
	 *
	 * Set maxbytes to -1 to disable file size limit.
	 *
	 * @param int $maxbytes maximum number of bytes
	 * @return string contents of file
	 * @throws FileNotFoundException, FileException
	 */

	function GetContents($maxbytes = -1)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (!is_int($maxbytes) || $maxbytes < -1)
			throw new ValidationException(LOCALE_LANG_ERRMSG_INVALID_TYPE, __METHOD__, __LINE__);

		$contents = $this->GetContentsAsArray($maxbytes);

		return implode("\n", $contents);
	}

	/**
	 * Returns the contents of a file in an array.
	 *
	 * Set maxbytes to -1 to disable file size limit.
	 *
	 * @param int $maxbytes maximum number of bytes
	 * @return array contents of file
	 * @throws FileNotFoundException, FileException
	 */

	function GetContentsAsArray($maxbytes = -1)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (!is_int($maxbytes) || $maxbytes < -1)
			throw new ValidationException(LOCALE_LANG_ERRMSG_INVALID_TYPE, __METHOD__, __LINE__);

		if (! $this->Exists() )
			throw new FileNotFoundException($this->filename, COMMON_INFO);

		// TODO: use some other semaphore -- this breaks with maxbytes set
		//if (is_null($this->contents)) {

		// If readable by webconfig, then use file_get_contents
		// If file_get_contents fails, try shellexec

		if (is_readable("$this->filename")) {
			$maxlen = ($maxbytes >= 0) ? $maxbytes : null;
			$contents = file_get_contents("$this->filename", false, NULL, 0, $maxlen);

			if ($contents) {
				$this->contents = explode("\n", rtrim($contents));
				return $this->contents;
			}
		}

		try {
			$shell = new ShellExec();
			if ($maxbytes >= 0)
				$exitcode = $shell->Execute(File::CMD_HEAD, "-c $maxbytes $this->filename", true);
			else
				$exitcode = $shell->Execute(File::CMD_CAT, escapeshellarg($this->filename), true);
		} catch (Exception $e) {
			throw new FileException($e->getMessage(), COMMON_WARNING);
		}

		if ($exitcode != 0)
			throw new FileException($shell->GetFirstOutputLine(), COMMON_WARNING);

		$this->contents = $shell->GetOutput();

		return $this->contents;
	}

	/**
	 * Returns the contents of a file that match the given regular expression.
	 *
	 * Set maxbytes to -1 to disable file size limit.
	 *
	 * @param string $regex search string
	 * @param int $maxbytes maximum number of bytes
	 * @return array contents of file
	 * @throws FileNotFoundException, FileException
	 */

	function GetSearchResults($regex, $maxbytes = -1)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (!is_int($maxbytes) || $maxbytes < -1)
			throw new ValidationException(LOCALE_LANG_ERRMSG_INVALID_TYPE, __METHOD__, __LINE__);

		$contents = $this->GetContentsAsArray();

		$result = array();
		$count = 0;

		foreach ($contents as $line) {
			if (preg_match("/$regex/", $line)) {
				$result[] = $line;
				if ($maxbytes != -1) {
					$count += strlen($line);
					if ($count > $maxbytes)
						break;
				}
			}
		}

		return $result;
	}

	/**
	 * Returns a value for a given unique regular expression.
	 *
	 * This method is handy for simple configuration files with key/value pairs.  The
	 * method will return a FileNoMatchException error if no match was made.
	 *
	 * @param string $key search string
	 * @return string value for the give key
	 * @throws ValidationException, FileNoMatchException, FileNotFoundException, FileException
	 */

	function LookupValue($key)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		// TODO: input validation (if any?)

		$contents = $this->GetContentsAsArray();

		foreach ($contents as $line) {
			if (preg_match($key, $line)) {
				$result = preg_replace($key, "", $line);
				return trim($result);
			}
		}

		throw new FileNoMatchException($this->filename, COMMON_INFO, $key);
	}

	/**
	 * Checks the existence of the file.
	 *
	 * @return boolean true if file exists
	 * @throws FileException
	 */

	function Exists()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if ($this->superuser) {
			try {
				$shell = new ShellExec();
				$exitcode = $shell->Execute(File::CMD_LS, escapeshellarg($this->filename), true);
			} catch (Exception $e) {
				throw new FileException($e->GetMessage(), COMMON_WARNING);
			}

			if ($exitcode == 0)
				return true;
			else
				return false;
		} else {
			clearstatcache();
			if (file_exists("$this->filename"))
				return true;
			else
				return false;
		}
	}

	/**
	 * Returns the file size.
	 *
	 * @return int the file size
	 * @throws FileException
	 */

	function GetSize()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (! $this->Exists())
			throw new FileNotFoundException($this->filename, COMMON_INFO);

		try {
			$shell = new ShellExec();
			$args = "-loL " . escapeshellarg($this->filename); 
			$exitcode = $shell->Execute(self::CMD_LS, $args, true);
		} catch (Exception $e) {
			throw new FileException($e->GetMessage(), COMMON_WARNING);
		}

		if ($exitcode == 0) {
			$shell->GetLastOutputLine();
			$parts = explode(" ", $shell->GetLastOutputLine());
			return (int)$parts[4];
		} else {
			throw new EngineException(LOCALE_LANG_ERRMSG_WEIRD, COMMON_WARNING);
		}
	}

	/**
	 * Returns the MD5 hash of the file.
	 *
	 * @return string the MD5 hash
	 * @throws FileException
	 */

	function GetMd5()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (! $this->Exists())
			throw new FileNotFoundException($this->filename, COMMON_INFO);

		if ($this->superuser) {
			$md5 = md5_file("$this->filename");
			if ($md5)
				return $md5;
			try {
				$shell = new ShellExec();
				$exitcode = $shell->Execute(self::CMD_MD5, escapeshellarg($this->filename), true);
			} catch (Exception $e) {
				throw new FileException($e->GetMessage(), COMMON_WARNING);
			}

			if ($exitcode == 0) {
				$md5 = trim(ereg_replace("$this->filename", "", $shell->GetLastOutputLine()));
				return $md5;
			} else {
				throw new EngineException(LOCALE_LANG_ERRMSG_WEIRD, COMMON_WARNING);
			}
		} else {
			return md5_file($this->GetFilename());
		}
	}

	/**
	 * Changes file mode.
	 *
	 * @param string $mode mode of the file
	 * @return void
	 * @throws ValidationException, FileNotFoundException, FilePermissionsException, FileException
	 */

	function Chmod($mode)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		// TODO: validate $mode

		if (! $this->Exists())
			throw new FileNotFoundException($this->filename, COMMON_NOTICE);

		try {
			$shell = new ShellExec();
			$exitcode = $shell->Execute(File::CMD_CHMOD, " $mode " . escapeshellarg($this->filename), true);
		} catch (Exception $e) {
			throw new FileException($e->GetMessage(), COMMON_WARNING);
		}

		if ($exitcode != 0)
			throw new FilePermissionsException(FILE_LANG_ERRMSG_CHMOD . " - " . $this->filename, COMMON_WARNING);
	}


	/**
	 * Changes file owner and/or group.
	 *
	 * Leave the owner or group blank if you do not want change one or the other.
	 *
	 * @param string $owner file owner
	 * @param string $group file group
	 * @return void
	 * @throws ValidationException, FileNotFoundException, FilePermissionsException, FileException
	 */

	function Chown($owner, $group)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (empty($owner) && empty($group))
			throw new ValidationException(LOCALE_LANG_ERRMSG_NO_ENTRIES, __METHOD__, __LINE__);

		// TODO: more input validation

		if (! $this->Exists())
			throw new FileNotFoundException($this->filename, COMMON_NOTICE);

		$shell = new ShellExec();

		if (! empty($owner)) {
			try {
				$exitcode = $shell->Execute(File::CMD_CHOWN, "$owner " . escapeshellarg($this->filename), true);
			} catch (Exception $e) {
				throw new FileException($e->getMessage(), COMMON_WARNING);
			}

			if ($exitcode != 0)
				throw new FilePermissionsException(FILE_LANG_ERRMSG_CHOWN . " - " . $this->filename, COMMON_WARNING);
		}

		if (! empty($group)) {
			try {
				$exitcode = $shell->Execute(File::CMD_CHOWN, " :$group " . escapeshellarg($this->filename), true);
			} catch (Exception $e) {
				throw new FileException($e->getMessage(), COMMON_WARNING);
			}

			if ($exitcode != 0)
				throw new FilePermissionsException(FILE_LANG_ERRMSG_CHOWN . " - " . $this->filename, COMMON_WARNING);
		}
	}

	/**
	 * Returns the octal permissions of the current file.
	 *
	 * @return string file permissions
	 * @throws FileNotFoundException, FileException
	 */

	function GetPermissions()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		clearstatcache();

		if (! $this->Exists())
			throw new FileNotFoundException($this->filename, COMMON_INFO);

		// TODO: this will fail on files that user webconfig cannot read (protected directories).
		// Added FileException to docs to futureproof API.

		return substr(sprintf('%o', fileperms("$this->filename")), -4);
	}

	/**
	 * Returns the last modified date of the file.
	 *
	 * @return long representing time file was last modified
	 * @throws FileNotFoundException, FileException
	 */

	function LastModified()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (! $this->Exists())
			throw new FileNotFoundException($this->filename, COMMON_INFO);

		if ($this->superuser) {
			try {
				$shell = new ShellExec();
				$args = "-l --time-style=full-iso " . escapeshellarg($this->filename); 
				$exitcode = $shell->Execute(self::CMD_LS, $args, true);
			} catch (Exception $e) {
				throw new FileException($e->GetMessage(), COMMON_WARNING);
			}

			if ($exitcode == 0) {
				$shell->GetLastOutputLine();
				$parts = explode(" ", $shell->GetLastOutputLine());
				return strtotime($parts[6] . " " . substr($parts[7], 0, 8) . " " . $parts[8]);
			} else {
				throw new EngineException(LOCALE_LANG_ERRMSG_WEIRD, COMMON_WARNING);
			}
		} else {
			clearstatcache();
			return filemtime("$this->filename");
		}
	}


	/**
	 * Creates a file on the system.
	 *
	 * @param string $owner file owner
	 * @param string $group file group
	 * @param string $mode mode of the file
	 * @return void
	 * @throws FileAlreadyExistsException, FilePermissionsException, FileException
	 */

	function Create($owner, $group, $mode)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		clearstatcache();

		if ($this->Exists())
			throw new FileAlreadyExistsException($this->filename, COMMON_NOTICE);

		try {
			$shell = new ShellExec();
			$shell->Execute(File::CMD_TOUCH, escapeshellarg($this->filename), true);

			if ($owner || $group)
				$this->Chown($owner, $group);

			if ($mode)
				$this->Chmod($mode);

		} catch (FilePermissionsException $e) {
			// Delete file if permissions barf, rethrow
			$this->Delete();
			throw new FilePermissionsException($e->GetMessage(), COMMON_WARNING);
		} catch (Exception $e) {
			throw new FileException($e->getMessage(), COMMON_WARNING);
		}

		$this->contents = null;
	}


	/**
	 * Deletes the file.
	 *
	 * @return void
	 * @throws FileNotFoundException, FileException
	 */

	function Delete()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		clearstatcache();

		if (! $this->Exists())
			throw new FileNotFoundException($this->filename, COMMON_NOTICE);

		try {
			$shell = new ShellExec();
			$shell->Execute(File::CMD_RM, escapeshellarg($this->filename), true);
		} catch (Exception $e) {
			throw new FileException($e->getMessage(), COMMON_WARNING);
		}

		$this->contents = null;
	}

	/**
	 * Checks to see if specified file is a directory.
	 *
	 * @return boolean true if file is a directory
	 * @throws FileException
	 */

	function IsDirectory()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$isdir = false;

		if ($this->superuser) {

			try {
				$shell = new ShellExec();
				$shell->Execute(File::CMD_FILE, escapeshellarg($this->filename), true);

				// TODO -- a hack
				if (preg_match("/directory/", $shell->GetOutput(0))) {
					$isdir = true;
				}

			} catch (Exception $e) {
				throw new FileException($e->getMessage(),COMMON_WARNING);
			}
		} else {
			$isdir = is_dir("$this->filename");
		}

		return $isdir;
	}

	/**
	 * Checks to see if specified file is a symbolic link.
	 *
	 * @return integer  0 if not, 1 if active sym link, -1 if broken sym link
	 * @throws FileException
	 */

	function IsSymLink()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$issym = 0;

		if ($this->superuser) {

			try {
				$shell = new ShellExec();
				$shell->Execute(File::CMD_FILE, escapeshellarg($this->filename), true);

				// TODO -- a hack
				if (preg_match("/symbolic link/", $shell->GetFirstOutputLine())) {
					if (preg_match("/broken/", $shell->GetFirstOutputLine()))
						$issym = -1;
					else
						$issym = 1;
				} else {
					$issym = 0;
				}

			} catch (Exception $e) {
				throw new FileException($e->getMessage(),COMMON_WARNING);
			}
		} else {
			if (is_link("$this->filename")) {
				if (! file_exists(readlink("$this->filename")))
					$issym = -1;
				else
					$issym = 1;
			} else {
				$issym = 0;
			}
		}

		return $issym;
	}

	/**
	 * Replaces the contents of the given tempfile to this file.
	 *
	 * This is basically a "mv" with the following behavior:
	 *  - This file (the one passed to the constructor) must exist.
	 *  - The tempfile is deleted if successful.
	 *  - The tempfile will take on the same file permissions and ownership as the target file.
	 *
	 * @param string $tempfile temp file
	 * @return void
	 * @throws FileNotFoundException FileException
	 */

	function Replace($tempfile)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (! file_exists($tempfile))
			throw FileNotFoundException($tempfile, COMMON_NOTICE);

		if (! $this->Exists())
			throw FileNotFoundException($this->filename, COMMON_NOTICE);

		$tempfile = escapeshellarg($tempfile);
		$thisfile = escapeshellarg($this->filename);

		try {
			$shell = new ShellExec();
			$exitcode = $shell->Execute(self::CMD_REPLACE, "$tempfile $thisfile", true);
		} catch (Exception $e) {
			throw new FileException($e->getMessage(), COMMON_WARNING);
		}

		if ($exitcode != 0) {
			$errmsg = $shell->GetFirstOutputLine();
			throw new FileException($errmsg, COMMON_WARNING);
		}

		$this->contents = null;
	}


	/**
	 * Writes array data to a file.
	 *
	 * The method does not automatically add a newline - that is up to you!
	 * This method will return an error if the file does not exist.
	 *
	 * @param  array  $contents  an array containing output lines
	 * @return void
	 */

	function DumpContentsFromArray($contents)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$tempfile = tempnam(COMMON_TEMP_DIR, basename("$this->filename"));

		if (!($fh_t = @fopen($tempfile, "w"))) {
			$this->AddValidationError(FILE_LANG_ERRMSG_OPEN . $tempfile,__METHOD__,__LINE__);
		} else {
			if ($contents)
				fputs($fh_t, implode("\n", $contents) . "\n");

			fclose($fh_t);

			$this->Replace($tempfile);
		}
	}

	/**
	 * Appends data to a file.
	 *
	 * The method does not automatically add a newline - that is up to you!
	 *
	 * @param  string $data line (or lines) to append to the file
	 * @return void
	 * @throws FileNotFoundException FileException
	 */

	function AddLines($data)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$tempfile = tempnam(COMMON_TEMP_DIR, basename("$this->filename"));

		try {
			$contents = $this->GetContents();
		} catch (Exception $e) {
			throw $e;
		}

		if (!($fh_t = @fopen($tempfile, "w")))
			throw new FileException(FILE_LANG_ERRMSG_OPEN . " - " . $tempfile, COMMON_NOTICE);

		// Remove and then re-insert newline on files...
		// this catches invalid files with no newline at the end
		trim($contents);

		if ($contents)
			fputs($fh_t, $contents . "\n");

		fputs($fh_t, $data);
		fclose($fh_t);

		$this->Replace($tempfile);

		$this->contents = null;
	}

	/**
	 * Appends a line (or lines) to a file at a particular location in the file.
	 *
	 * @param string $data line(s) to insert into file
	 * @param string $after regular expression defining the file location
	 * @return void
	 * @throws FileNoMatchException, FileNotFoundException, FileException
	 */

	function AddLinesAfter($data, $after)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$tempfile = tempnam(COMMON_TEMP_DIR, basename("$this->filename"));

		$lines = $this->GetContentsAsArray();

		if (!($fh_t = @fopen($tempfile, "w")))
			throw new FileException(FILE_LANG_ERRMSG_OPEN . " - " . $tempfile, COMMON_NOTICE);

		$match = false;

		foreach ($lines as $line) {
			fputs($fh_t, $line . "\n");

			if (preg_match($after, $line) && (!$match)) {
				$match = true;
				fputs($fh_t, $data);
			}
		}

		fclose($fh_t);

		if (! $match) {
			throw new FileNoMatchException($tempfile, COMMON_NOTICE, $after);
			unlink($tempfile);
		}

		$this->Replace($tempfile);

		$this->contents = null;
	}

	/**
	 * Prepends a line (or lines) to a file at a particular location in the file.
	 *
	 * @param string $data line(s) to insert into file
	 * @param string $before regular expression defining the file location
	 * @return void
	 * @throws FileNoMatchException, FileNotFoundException, FileException
	 */

	function AddLinesBefore($data, $before)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$tempfile = tempnam(COMMON_TEMP_DIR, basename("$this->filename"));

		$lines = $this->GetContentsAsArray();

		if (!($fh_t = @fopen($tempfile, "w")))
			throw new FileException(FILE_LANG_ERRMSG_OPEN . " - " . $tempfile, COMMON_NOTICE);

		$match = false;

		foreach ($lines as $line) {
			if (preg_match($before, $line) && (!$match)) {
				$match = true;
				fputs($fh_t, $data);
			}

			fputs($fh_t, $line . "\n");
		}

		fclose($fh_t);

		if (! $match) {
			throw new FileNoMatchException($tempfile, COMMON_NOTICE, $before);
			unlink($tempfile);
		}

		$this->Replace($tempfile);

		$this->contents = null;
	}

	/**
	 * Removes lines from a file that match the regular expression.
	 *
	 * @param string $search regular expression used to match removed lines
	 * @return integer number of lines deleted
	 * @throws FileNotFoundException Exception (inherited from GetContents)
	 */

	function DeleteLines($search)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$deleted = $this->ReplaceLines($search, '');

		$this->contents = null;

		return $deleted;
	}

	/**
	 * Prepends lines with a string (usually a comment character).
	 *
	 * Any line matching the search string will be changed.
	 *
	 * @param  string  $prepend  prepend string
	 * @param  string  $search  regular expression used to match removed lines
	 * @return  boolean  true if any matches were made
	 * @throws  FileNotFoundException Exception (inherited from GetContentsAsArray)
	 */

	function PrependLines($search, $prepend)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$prependlines = false;

		$tempfile = tempnam(COMMON_TEMP_DIR, basename("$this->filename"));

		$lines = $this->GetContentsAsArray();

		if (!($fh_t = @fopen($tempfile, "w"))) {
			$this->AddValidationError(FILE_LANG_ERRMSG_OPEN . $tempfile,__METHOD__,__LINE__);
		} else {
			$match = false;
			foreach ($lines as $line) {
				if (preg_match($search, $line)) {
					fputs($fh_t, $prepend . $line . "\n");
					$match = true;
				} else {
					fputs($fh_t, $line . "\n");
				}
			}

			fclose($fh_t);

			if (! $match) {
				$this->AddValidationError(LOCALE_LANG_ERRMSG_NO_MATCH,__METHOD__,__LINE__);
				unlink($tempfile);
			} else {
				$prependlines = $this->Replace($tempfile);
			}
		}

		return $prependlines;
	}

	/**
	 * Searches the file with the given regular expression and returns the first match.
	 *
	 * @param string $search regular expression
	 * @return string matching line
	 * @throws ValidationException, FileNoMatchException, FileNotFoundException, FileException
	 */

	function LookupLine($search)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		// TODO: validation (e.g. search must have two slashes)

		$lines = $this->GetContentsAsArray();

		foreach ($lines as $line) {
			if (preg_match($search, $line)) {
				return $line;
			}
		}

		throw new FileNoMatchException($this->filename, COMMON_INFO, $search);
	}

	/**
	 * Similar to LookupValue, except you can specify a subsection of the target file.
	 *
	 * The start and end are regular expressions.  This can be handy in Apache-style configuration
	 * files (e.g. configuring a particular Virtual Host).  This method will
	 * return a PLATFORM_EXCEPTION_LOOKUP_NO_MATCH error if no match was made.
	 *
	 * @param  string  $key  search string
	 * @param  string  $start  regular expression specifying the start line
	 * @param  string  $end  regular expression specifying the end line
	 * @return  string  value for the give key
	 * @throws  FileNotFoundException Exception (inherited from GetContentsAsArray)
	 * @throws  FileNoMatchException
	 */

	function LookupValueBetween($key, $start, $end)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		try {
			$lines = $this->GetContentsAsArray();
		} catch (Exception $e) {
			throw $e;
		}

		// Find start tag
		foreach ($lines as $line) {
			if (preg_match($start, $line))
				break;

			array_shift($lines);
		}

		foreach ($lines as $line) {
			// Bail if see the end tag

			if (preg_match($end, $line))
				break;

			if (preg_match($key, $line)) {
				$result = trim(preg_replace($key, "", $line));

				if (!strlen($result))
					return true;

				return $result;
			}
		}

		throw new FileNoMatchException($this->filename, COMMON_INFO, $key);
	}

	/**
	 * Copies the file to new location.
	 *
	 * @param string $destination destination location
	 * @return void
	 * @throws FileException, ValidationException
	 */

	function CopyTo($destination)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		// TODO: validate destination

		try {
			$shell = new ShellExec();
			$exitcode = $shell->Execute(File::CMD_COPY, "-a " . escapeshellarg($this->filename) . " " . escapeshellarg($destination), true);
		} catch (Exception $e) {
			throw new FileException($e->getMessage(), COMMON_WARNING);
		}

		if ($exitcode != 0) {
			$errmsg = $shell->GetOutput();
			throw new FileException($errmsg[0], COMMON_WARNING);
		}
	}

	/**
	 * Moves the file to new location.
	 *
	 * @see Replace
	 * @param string $destination destination location
	 * @return void
	 * @throws FileException, ValidationException
	 */

	function MoveTo($destination)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		// TODO: validate destination

		try {
			$shell = new ShellExec();
			$exitcode = $shell->Execute(File::CMD_MOVE, escapeshellarg($this->filename) . " " . escapeshellarg($destination), true);
		} catch (Exception $e) {
			throw new FileException($e->getMessage(),COMMON_WARNING);
		}

		if ($exitcode != 0) {
			$errmsg = $shell->GetOutput();
			throw new FileException($errmsg[0], COMMON_WARNING);
		}

		$this->filename = $destination;
	}

	/**
	 * Replaces lines in a section of a file for Apache-style configuration files.
	 *
	 * Specify the (non-unique) start and end tags along with a search value that uniquely defines the section.
	 *
	 * @param string $start regular expression specifying the start line
	 * @param string $end regular expression specifying the end line
	 * @param string $search regular expression for the search string
	 * @param string $replacement replacement line
	 * @return void
	 * @throws FileNotFoundException Exception (inherited from GetContentsAsArray)
	 */

	function ReplaceLinesBetween($search, $replacement, $start, $end)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$replaced = false;

		$tempfile = tempnam(COMMON_TEMP_DIR, basename("$this->filename"));

		$lines = $this->GetContentsAsArray();

		if (!($fh_t = @fopen($tempfile, "w"))) {
			$this->AddValidationError(FILE_LANG_ERRMSG_OPEN . $tempfile,__METHOD__,__LINE__);
		} else {

			// Find start tag
			$match = false;
			foreach ($lines as $line) {
				if (preg_match($start, $line))
					break;

				fputs($fh_t, $line . "\n");

				array_shift($lines);
			}

			foreach ($lines as $line) {
				// Bail if see the end tag

				if (preg_match($end, $line))
					break;

				if (preg_match($search, $line)) {
					$match = true;

					if (strlen($replacement))
						fputs($fh_t, $replacement);
				} else {
					fputs($fh_t, $line . "\n");
				}

				array_shift($lines);
			}

			foreach ($lines as $line)
			fputs($fh_t, $line . "\n");

			fclose($fh_t);

			if (! $match) {
				$this->AddValidationError(LOCALE_LANG_ERRMSG_NO_MATCH,__METHOD__,__LINE__);
				unlink($tempfile);
			} else {
				$replaced = $this->Replace($tempfile);
			}
		}

		return $match;
	}

	/**
	 * Replaces a line (defined by a regular expression) with a replacement.
	 *
	 * @param string $search search string
	 * @param string $replacement replacement line (or lines)
	 * @param integer $maxreplaced maximum number of matches to make
	 * @return integer number of replacements made
	 * @throws FileException, ValidationException
	 */

	function ReplaceLines($search, $replacement, $maxreplaced = -1)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		// TODO: add validation

		$replaced = 0;

		$tempfile = tempnam(COMMON_TEMP_DIR, basename("$this->filename"));

		$lines = $this->GetContentsAsArray();

		if (!($fh_t = @fopen($tempfile, "w")))
			throw new FileException(FILE_LANG_ERRMSG_OPEN . " - " . $tempfile, COMMON_NOTICE);

		// Find start tag
		foreach ($lines as $line) {
			if (preg_match($search, $line) && (($replaced < $maxreplaced) || $maxreplaced == -1)) {
				fputs($fh_t, $replacement);
				$replaced++;
			} else {
				fputs($fh_t, $line . "\n");
			}
		}

		fclose($fh_t);

		if ($replaced == 0) {
			unlink($tempfile);
			return 0;
		} else {
			$this->Replace($tempfile);
		}

		$this->contents = null;

		return $replaced;
	}

	/**
	 * Replaces a line defined by a regular expression.
	 *
	 * @param string $search search string
	 * @param string $replacement replacement line (or lines)
	 * @return integer number of replacements made
	 * @throws FileNotFoundException, FileException
	 */

	// TODO: deprecate
	function ReplaceOneLine($search, $replacement)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		return $this->ReplaceLines($search, $replacement, 1);
	}

	/**
	 * Replaces a line defined by a regular expression.
	 *
	 * This method will throw a PLATFORM_EXCEPTION_LOOKUP_NO_MATCH
	 * if a match is not found.  This version differs from ReplaceOneLine
	 * in that it uses preg_replace to do the substitution.  Thus you can
	 * use parts of a pattern match in the replacement (ie: $1, $2, etc).
	 *
	 * @param  string  $search  search expression
	 * @param  string  $replacement  replacement expression
	 * @return  boolean  true if any replacements were made
	 * @throws  FileNotFoundException Exception (inherited from GetContentsAsArray)
	 */

	function ReplaceOneLineByPattern($search, $replacement)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$replaced = false;

		$tempfile = tempnam(COMMON_TEMP_DIR, basename("$this->filename"));

		$lines = $this->GetContentsAsArray();

		if (!($fh_t = @fopen($tempfile, "w"))) {
			$this->AddValidationError(FILE_LANG_ERRMSG_OPEN . $tempfile,__METHOD__,__LINE__);
		} else {
			$match = false;
			foreach ($lines as $line) {
				if ((preg_match($search, $line)) && !$match) {
					$match = preg_replace($search, $replacement, $line);

					if ($match)
						fputs($fh_t, $match . "\n");
				} else
					fputs($fh_t, $line . "\n");
			}

			fclose($fh_t);

			if (! $match) {
				$this->AddValidationError(LOCALE_LANG_ERRMSG_NO_MATCH,__METHOD__,__LINE__);
				unlink($tempfile);
			} else {
				$replaced = $this->Replace($tempfile);
			}
		}

		return $replaced;
	}

	/**
	 * Replaces all matching lines defined by a regular expression.
	 *
	 * This method will throw a PLATFORM_EXCEPTION_LOOKUP_NO_MATCH
	 * if a match is not found.
	 *
	 * @param  string  $search  search expression
	 * @param  string  $replacement  replacement expression
	 * @return  boolean  true if any replacements were made
	 * @throws  FileNotFoundException Exception (inherited from GetContentsAsArray)
	 */

	function ReplaceLinesByPattern($search, $replacement)
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$replaced = false;

		$tempfile = tempnam(COMMON_TEMP_DIR, basename("$this->filename"));

		$lines = $this->GetContentsAsArray();

		if (!($fh_t = @fopen($tempfile, "w"))) {
			$this->AddValidationError(FILE_LANG_ERRMSG_OPEN . $tempfile,__METHOD__,__LINE__);
		} else {
			$match = false;
			foreach ($lines as $line) {
				if ((preg_match($search, $line))) {
					$match = preg_replace($search, $replacement, $line);

					if ($match)
						fputs($fh_t, $match . "\n");
				} else
					fputs($fh_t, $line . "\n");
			}

			fclose($fh_t);

			if (! $match) {
				$this->AddValidationError(LOCALE_LANG_ERRMSG_NO_MATCH,__METHOD__,__LINE__);
				unlink($tempfile);
			} else {
				$replaced = $this->Replace($tempfile);
			}
		}

		return $replaced;
	}

	/**
	 * @access private
	 */

	function __destruct()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__destruct();
	}
}

// vim: syntax=php ts=4
?>

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 66
活跃值: (835)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
Os.class.php

<?php

///////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 Point Clark Networks.
//
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////

/**
 * Operating system information.
 *
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @package Api
 * @copyright Copyright 2006, Point Clark Networks
 * @version  4.0, 1-14-2006
 */

///////////////////////////////////////////////////////////////////////////////
// D E P E N D E N C I E S
///////////////////////////////////////////////////////////////////////////////

require_once('Engine.class.php');
require_once('File.class.php');

///////////////////////////////////////////////////////////////////////////////
// C L A S S
///////////////////////////////////////////////////////////////////////////////

/**
 * Software package class.
 *
 * @package Api
 */

class Os extends Engine
{
	///////////////////////////////////////////////////////////////////////////////
	// M E M B E R S
	///////////////////////////////////////////////////////////////////////////////

	private $os = null;
	private $version = null;
	private $previous_os = null;
	private $previous_version = null;

	const FILE_RELEASE = '/etc/release';
	const FILE_OLD_RELEASE = '/etc/system/release.previous';
	const FILE_VENDOR = '/usr/share/system/settings/vendor';

	///////////////////////////////////////////////////////////////////////////////
	// M E T H O D S
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * Os constructor.
	 */

	function __construct()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__construct();

		require_once(GlobalGetLanguageTemplate(__FILE__));
	}

	/**
	 * Returns the name of the operating system/distribution.
	 *
	 * @return string OS name
	 * @throws EngineException
	 */

	public function GetName()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (is_null($this->os))
			$this->_LoadConfig();

		return $this->os;
	}

	/**
	 * Returns version from previous installed version (upgrade).
	 *
	 * @return string OS version, 0 if none exists
	 * @throws EngineException
	 */

	public function GetPreviousVersion()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		try {
			$file = new File(self::FILE_OLD_RELEASE);
			if (! $file->Exists())
				return 0;

			$contents = $file->GetContents();
		} catch (Exception $e) {
			throw new EngineException($e->getMessage(), COMMON_ERROR);
		}

		$osinfo = explode(" release ", $contents);

		if (count($osinfo) != 2)
			throw new EngineException(OS_LANG_ERRMSG_NAME_UNKNOWN, COMMON_ERROR);

		return $osinfo[1];
	}

	/**
	 * Returns the vendor code for the operating system/distribution.
	 *
	 * @return string vendor code
	 * @throws EngineException
	 */

	public function GetVendorCode()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$vendor = "";

		try {
			$file = new File(self::FILE_VENDOR);
			$vendor = $file->LookupValue("/^vendor\s*=\s*/");
		} catch (Exception $e) {
			throw new EngineException($e->getMessage(), COMMON_ERROR);
		}

		return $vendor;
	}

	/**
	 * Returns the version of the operating system/distribution.
	 *
	 * @return string OS version
	 * @throws EngineException
	 */

	public function GetVersion()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (is_null($this->version))
			$this->_LoadConfig();

		return $this->version;
	}

	/**
	 * Populates version and name fields.
	 *
	 * @access private
	 * @throws EngineException
	 */

	protected function _LoadConfig()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		try {
			$file = new File(self::FILE_RELEASE);
			$contents = $file->GetContents();
		} catch (Exception $e) {
			throw new EngineException($e->getMessage(), COMMON_ERROR);
		}

		$osinfo = explode(" release ", $contents);

		if (count($osinfo) != 2)
			throw new EngineException(OS_LANG_ERRMSG_NAME_UNKNOWN, COMMON_ERROR);

		$this->os = $osinfo[0];
		$this->version = $osinfo[1];
	}

	/**
	 * @access private
	 */

	public function __destruct()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__destruct();
	}
}

// vim: syntax=php ts=4
?>


==========================================================

Register.class.php

<?php

///////////////////////////////////////////////////////////////////////////////
//
// Copyright 2003-2006 Point Clark Networks.
//
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
//
// Eventually, this will get merged with the WebServices class. For now, this
// class will handle its own request to the Service Delivery Network.
//
///////////////////////////////////////////////////////////////////////////////

/**
 * System registration class.
 *
 * @package Api
 * @subpackage WebServices
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2003-2006, Point Clark Networks
 */

///////////////////////////////////////////////////////////////////////////////
// D E P E N D E N C I E S
///////////////////////////////////////////////////////////////////////////////

require_once('ConfigurationFile.class.php');
require_once('Engine.class.php');
require_once('File.class.php');
require_once('Os.class.php');
require_once('Suva.class.php');
require_once('WebServices.class.php');

///////////////////////////////////////////////////////////////////////////////
// C L A S S
///////////////////////////////////////////////////////////////////////////////

/**
 * System registration class.
 *
 * Registers your system to the Service Delivery Network (SDN).  Instead of
 * going over the network to check the registration status *every* time, we
 * simply set a local file to indicate that the system has been registered.
 *
 * @package Api
 * @subpackage WebServices
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2003-2006, Point Clark Networks
 */

class Register extends Engine
{
	const URL_SERVICES = "webservice_services.jsp";
	const URL_DEVICE = "webservice_device.jsp";
	const URL_USER = "webservice_user.jsp";
	const TYPE_ADD = "Add";
	const TYPE_UPGRADE = "Upgrade";
	const TYPE_REINSTALL = "Reinstall";

	protected $hostkey = "";
	protected $langcode = "en_US";
	protected $vendor = "";
	protected $config = array();
	protected $is_loaded = false;

	///////////////////////////////////////////////////////////////////////////////
	// M E T H O D S
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * Register constructor.
	 */

	function __construct()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__construct();

		require_once(GlobalGetLanguageTemplate(__FILE__));
	}

	/**
	 * Returns registration status.
	 *
	 * @return boolean registration status
	 */

	public function GetStatus()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (file_exists(WebServices::FILE_REGISTERED))
			return true;
		else
			return false;
	}


	/**
	 * Sets registration to true in local cache.
	 *
	 * @returns void
	 * @throws EngineException
	 */

	public function SetStatus()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$file = new File(WebServices::FILE_REGISTERED);

		try {
			if ($file->Exists())
				$file->Delete();

			$file->Create("root", "root", "0644");
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_ERROR);
		}
	}

	/**
	 * Resets the registration status.
	 *
	 * @param boolean $newkey flag to indicate host key regeneration
	 * @return void
	 * @throws EngineException, ValidationException
	 */

	public function Reset($newkey)
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (! is_bool($newkey))
			throw new ValidationException(LOCALE_LANG_ERRMSG_PARAMETER_IS_INVALID . " - newkey");

		if ($newkey) {
			$suva = new Suva();
			$this->hostkey = $suva->ResetHostkey();
		}

		$file = new File(WebServices::FILE_REGISTERED);

		try {
			if ($file->Exists())
				$file->Delete();
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_ERROR);
		}
	}

	/**
	 * Simple username/password check for an online account.
	 *
	 * @param string $username username
	 * @param string $password password
	 * @return array request response
	 * @throws
	 */

	public function Authenticate($username, $password)
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$response = $this->Request(
						self::URL_USER,
						"Authenticate",
						"&username=$username&password=$password"
					);

		if ($response['exitcode'] != 0)
			throw new WebServicesRemoteException($response['errormessage'], COMMON_WARNING);

		return $response;
	}

	/**
	 * Returns a list of valid licenses for the given account.
	 *
	 * @param string $username username
	 * @param string $password password
	 * @return array license list
	 */

	public function GetLicenseList($username, $password)
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		try {
			$os = new Os();
			$osname = $os->GetName();
			$osversion = $os->GetVersion();
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_WARNING);
		}

		$response = $this->Request(
						self::URL_DEVICE,
						"GetLicenses",
						"&username=$username&password=$password&osname=$osname&osversion=$osversion"
					);

		if ($response['exitcode'] == 20)
			throw new WebServicesNotRegisteredException($response['errormessage'], COMMON_WARNING);
		if ($response['exitcode'] != 0)
			throw new WebServicesRemoteException($response['errormessage'], COMMON_WARNING);

		// Parse the payload
		//------------------

		$payload = $response['payload'];
		$rawlicenses = preg_replace("/.*<licenses>/si", "", $payload);
		$rawlicenses = preg_replace("/<\/licenses>.*/si", "", $rawlicenses);

		if ($rawlicenses) {
			$licenses = explode("|", $rawlicenses);
			foreach ($licenses as $rawdetails) {
				$details = explode(",", $rawdetails);
				if (count($details) >= 4) {
					$licenseinfo["serial"] = $details[0];
					$licenseinfo["description"] = $details[1];
					$licenseinfo["name"] = $details[2];
					$licenseinfo["status"] = $details[3];
					$licenselist[] = $licenseinfo;
				}
			}
		}

		return $licenselist;
	}

	/**
	 * Returns a list of devices in the given account.
	 *
	 * @param string $username username
	 * @param string $password password
	 * @return array device list
	 */

	public function GetDeviceList($username, $password)
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$response = $this->Request(
						self::URL_DEVICE,
						"GetDeviceList",
						"&username=$username&password=$password"
					);

		if ($response['exitcode'] == 20)
			throw new WebServicesNotRegisteredException($response['errormessage'], COMMON_WARNING);
		if ($response['exitcode'] != 0)
			throw new WebServicesRemoteException($response['errormessage'], COMMON_WARNING);

		// Parse the payload
		//------------------

		$deviceinfo = array();
		$payload = $response['payload'];
		$rawdevices = preg_replace("/.*<devices>/si", "", $payload);
		$rawdevices = preg_replace("/<\/devices>.*/si", "", $rawdevices);

		if ($rawdevices) {
			$devices = explode("|", $rawdevices);
			foreach ($devices as $rawdetails) {
				$details = explode(",", $rawdetails);
				$deviceinfo['id'] = $details[0];
				$deviceinfo['name'] = $details[1];
				$deviceinfo['osname'] = $details[2];
				$deviceinfo['osversion'] = $details[3];
				$devicelist[] = $deviceinfo;
			}
		}

		return $devicelist;
	}

	/**
	 * Returns product end of license.
	 *
	 * @return integer date
	 */

	public function GetEndOfLicense()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$response = $this->Request(
						self::URL_DEVICE,
						"GetEndOfLicense",
						""
					);

		if ($response['exitcode'] == 20)
			throw new WebServicesNotRegisteredException($response['errormessage'], COMMON_WARNING);
		if ($response['exitcode'] != 0)
			throw new WebServicesRemoteException($response['errormessage'], COMMON_WARNING);

		// TODO: date should be localized 
		$rawdata = split("\|", $response['payload']);

		return $rawdata[1];
	}

	/**
	 * Returns product end of life.
	 *
	 * @return integer date
	 */

	public function GetEndOfLife()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$response = $this->Request(
						self::URL_DEVICE,
						"GetEndOfLife",
						""
					);

		if ($response['exitcode'] == 20)
			throw new WebServicesNotRegisteredException($response['errormessage'], COMMON_WARNING);
		if ($response['exitcode'] != 0)
			throw new WebServicesRemoteException($response['errormessage'], COMMON_WARNING);

		// TODO: date should be localized 
		$rawdata = split("\|", $response['payload']);

		return $rawdata[1];
	}

	/**
	 * Returns services and subscription status.
	 *
	 * @return array service and subscription status
	 */

	function GetServiceList()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$response = $this->Request(
						self::URL_SERVICES,
						"GetList",
						"username=unused"
					);

		if ($response['exitcode'] == 20)
			throw new WebServicesNotRegisteredException($response['errormessage'], COMMON_WARNING);
		if ($response['exitcode'] != 0)
			throw new WebServicesRemoteException($response['errormessage'], COMMON_WARNING);

		// Parse the payload
		//------------------

		$servicelist = array();
		$payload = $response['payload'];

		// TODO: add available/not available
		// TODO: help link should only be a URL (not a full href)

		if ($payload) {
			$services = explode("|", $payload);
			foreach($services as $rawdetails) {
				$details = explode(",", $rawdetails);
				$serviceinfo['name'] = $details[0];
				$serviceinfo['help'] = $details[1];

				if ($details[2] == "true")
					$serviceinfo['state'] = true;
				else
					$serviceinfo['state'] = false;

				$servicelist[] = $serviceinfo;
			}
		}

		return $servicelist;
	}

	/**
	 * Returns the terms of service.
	 *
	 * @param string $username username
	 * @param string $password password
	 * @return string terms of service
	 */

	public function GetTermsOfService($username, $password)
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$response = $this->Request(
						self::URL_DEVICE,
						"GetTermsOfService",
						"&username=$username&password=$password"
					);

		if ($response['exitcode'] == 20)
			throw new WebServicesNotRegisteredException($response['errormessage'], COMMON_WARNING);
		if ($response['exitcode'] != 0)
			throw new WebServicesRemoteException($response['errormessage'], COMMON_WARNING);

		$tos = preg_replace("/.*<tos>/si", "", $response['payload']);
		$tos = preg_replace("/<\/tos>.*/si", "", $tos);

		return $tos;
	}

	/**
	 * Submits request to service delivery network.
	 *
	 * @param string $username username
	 * @param string $password password
	 * @param string $name system name
	 * @param string $serial serial number
	 * @param string $action type of registration
	 * @return void
	 */

	public function SubmitRegistration($username, $password, $name, $serial, $action, $terms)
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		try {
			$os = new Os();
			$osname = $os->GetName();
			$osversion = $os->GetVersion();
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_WARNING);
		}

		$response = $this->Request(
			self::URL_DEVICE,
			$action,
			"&username=$username&password=$password&name=$name" .
			"&serial=$serial&terms=$terms&osversion=$osversion"
			// "&serial=$serial&servicelevel=$servicelevel&terms=$terms&action=$action&osversion=$osversion"
		);

		if ($response['exitcode'] == 20)
			throw new WebServicesNotRegisteredException($response['errormessage'], COMMON_WARNING);
		if ($response['exitcode'] != 0)
			throw new WebServicesRemoteException($response['errormessage'], COMMON_WARNING);
	}

	/**
	 * @access private
	 */

	private function Request($resource, $action, $postfields)
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (! $this->isloaded)
			$this->_LoadConfig();

		// We use the WebServices locale just for consistency.
		$ws_locale = new WebServices("Register");

		// We always send the following information:
		// - hostkey
		// - vendor (reseller)
		// - language (error messages will be translated one of these days)

		if (!$this->hostkey || !$this->vendor || !$this->langcode)
			$this->LoadDefaultRequestFields();

		$postfields .= "&hostkey=" . $this->hostkey . "&vendor=" . $this->vendor . "&lang=" . $this->langcode;

		// Registration can take some time
		set_time_limit(60);

		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $this->config['sdn_url'] . "/$resource");
		curl_setopt($ch, CURLOPT_POSTFIELDS, "action=" . $action . $postfields);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_TIMEOUT, 60);
		curl_setopt($ch, CURLOPT_FAILONERROR, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

		$rawmessage = chop(curl_exec($ch));
		$error = curl_error($ch);
		$errno = curl_errno($ch);

		curl_close($ch);

		// Return useful errno messages for the most common errnos
		//--------------------------------------------------------

		if ($error || $errno) {
			$data["exitcode"] = 4;

			if ($errno == CURLE_COULDNT_RESOLVE_HOST)
				throw new EngineException(WEBSERVICES_LANG_ERRMSG_COULDNT_RESOLVE_HOST, COMMON_WARNING);
			else if ($errno == CURLE_OPERATION_TIMEOUTED)
				throw new EngineException(WEBSERVICES_LANG_ERRMSG_TIMEOUT, COMMON_WARNING);
			else
				throw new EngineException(WEBSERVICES_LANG_ERRMSG_CONNECTION_FAIL . " " . $error, COMMON_WARNING);
		} else {

			// Data is ok... return the payload and error message (if any)
			//------------------------------------------------------------

			if (!preg_match("/exit_code|\d|/", $rawmessage)) {
				throw new EngineException("invalid page or data", COMMON_WARNING);
			} else {
				$rawmessage = trim($rawmessage);

				$exitcode = preg_replace("/.*<exitcode>/si", "", $rawmessage);
				$exitcode = preg_replace("/<\/exitcode>.*/si", "", $exitcode);
				$errormessage = preg_replace("/.*<errormessage>/si", "", $rawmessage);
				$errormessage = preg_replace("/<\/errormessage>.*/si", "", $errormessage);
				$payload = preg_replace("/.*<payload>/si", "", $rawmessage);
				$payload = preg_replace("/<\/payload>.*/si", "", $payload);

				$data["exitcode"] = $exitcode;
				$data["errormessage"] = $errormessage;
				$data["payload"] = $payload;
			}
		}

		return $data;
	}

	/**
	 * Loads default remote request fields.
	 *
	 * @access private
	 * @return void
	 * @throws EngineException
	 */

	protected function LoadDefaultRequestFields()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		try {
			$suva = new Suva();
			$this->hostkey = $suva->GetHostkey();

			$os = new Os();
			$vendor = $os->GetVendorCode();

			$language= new Locale();
			$this->langcode = $language->GetLanguageCode();
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_ERROR);
		}
	}

	/**
	 * Loads configuration.
	 *
	 * @access private
	 * @return void
	 * @throws EngineException
	 */

	protected function _LoadConfig()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$configfile = new ConfigurationFile(WebServices::FILE_CONFIG);

		try {
			$this->config = $configfile->Load();
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_WARNING);
		}

		$this->is_loaded = true;
	}

	/**
	 * @access private
	 */

	public function __destruct()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__destruct();
	}
}

// vim: syntax=php ts=4
?>


==========================================================

Suva.class.php

<?php

///////////////////////////////////////////////////////////////////////////////
//
// Copyright 2003-2006 Point Clark Networks.
//
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////

/**
 * Suva server.
 *
 * @package Api
 * @subpackage Daemon
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2003-2006, Point Clark Networks
 */

///////////////////////////////////////////////////////////////////////////////
// D E P E N D E N C I E S
///////////////////////////////////////////////////////////////////////////////

require_once("Daemon.class.php");
require_once("ShellExec.class.php");

///////////////////////////////////////////////////////////////////////////////
// C L A S S
///////////////////////////////////////////////////////////////////////////////

/**
 * Suva utility class.
 *
 * The Suva class can be used to return the current host key.
 *
 * @package Api
 * @subpackage Daemon
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2003-2006, Point Clark Networks
 */

class Suva extends Daemon
{
	///////////////////////////////////////////////////////////////////////////////
	// C O N S T A N T S
	///////////////////////////////////////////////////////////////////////////////

	const CMD_SUVACTL = "/usr/local/suva/bin/suvactl";
	const PARAM_GET_HOSTKEY = "--get-hostkey";
	const PARAM_NEW_HOSTKEY = "--new-hostkey";

	///////////////////////////////////////////////////////////////////////////////
	// M E T H O D S
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * Suva constructor.
	 */

	function __construct() 
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__construct("suvad");

		require_once(GlobalGetLanguageTemplate(__FILE__));
	}

	/**
	 * Returns hostkey.
	 *
	 * @return string hostkey
	 * @throws EngineException
	 */

	function GetHostkey()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$shell = new ShellExec();

		try {
			$exitcode = $shell->Execute(Suva::CMD_SUVACTL, Suva::PARAM_GET_HOSTKEY, true);
			if ($exitcode != 0)
				throw new EngineException(SUVA_LANG_ERRMSG_HOSTKEY_NOT_FOUND, COMMON_WARNING);
		} catch (Exception $e) {
			throw new EngineException($e->getMessage(), COMMON_WARNING);
		}

		return implode(" ", $shell->GetOutput());
	}

	/**
	 * Resets a hostkey.
	 *
	 * @throws EngineException
	 */

	function ResetHostkey()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$shell = new ShellExec();

		try {
			$exitcode = $shell->Execute(Suva::CMD_SUVACTL, Suva::PARAM_NEW_HOSTKEY, true);
			if ($exitcode != 0)
				throw new EngineException($shell->GetLastOutputLine(), COMMON_WARNING);
		} catch (Exception $e) {
			throw new EngineException($e->getMessage(), COMMON_WARNING);
		}
	}

	/**
	 * @ignore
	 */

	function __destruct()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__destruct();
	}
}

// vim: syntax=php ts=4
?>


==========================================================

WebServices.class.php

<?php

///////////////////////////////////////////////////////////////////////////////
//
// Copyright 2003-2005 Point Clark Networks.
//
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////

/**
 * Web services class.
 *
 * @package Api
 * @subpackage WebServices
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2003-2006, Point Clark Networks
 */

///////////////////////////////////////////////////////////////////////////////
// D E P E N D E N C I E S
///////////////////////////////////////////////////////////////////////////////

require_once('ConfigurationFile.class.php');
require_once('Engine.class.php');
require_once('File.class.php');
require_once('Folder.class.php');
require_once('Locale.class.php');
require_once('Os.class.php');
require_once('Suva.class.php');

///////////////////////////////////////////////////////////////////////////////
// E X C E P T I O N  C L A S S E S
///////////////////////////////////////////////////////////////////////////////

/**
 * Remote web services exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2007, Point Clark Networks
 */

class WebServicesNoCacheException extends EngineException
{
	/**
	 * Web Services no cache exception constructor.
	 *
	 * @param string $errmsg error message
	 * @param int $code error code
	 */

	public function __construct()
	{
		parent::__construct(WEBSERVICES_LANG_SUBSCRIPTION_INFORMATION_UNAVAILABLE, COMMON_INFO);
	}
}

/**
 * Not registered exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class WebServicesNotRegisteredException extends EngineException
{
	/**
	 * Web Services not registered constructor.
	 */

	public function __construct()
	{
		parent::__construct(WEBSERVICES_LANG_SYSTEM_NOT_REGISTERED, COMMON_INFO);
	}
}

/**
 * Remote web services exception.
 *
 * @package Api
 * @subpackage Exception
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2006, Point Clark Networks
 */

class WebServicesRemoteException extends EngineException
{
	/**
	 * Web Services Exception constructor.
	 *
	 * @param string $errmsg error message
	 * @param int $code error code
	 */

	public function __construct($errmsg, $code)
	{
		parent::__construct($errmsg, $code);
	}
}

///////////////////////////////////////////////////////////////////////////////
// C L A S S
///////////////////////////////////////////////////////////////////////////////

/**
 * Web services class.
 *
 * The Web Service class interacts with Point Clark Networks' backend
 * systems -- the Service Delivery Network.  This network provides dynamic DNS,
 * Managed VPN, software updates, content filter updates, and much more.
 * This class will be replaced by direct SOAP calls in the future.
 *
 * @package Api
 * @subpackage WebServices
 * @author {@link http://www.pointclark.net/ Point Clark Networks}
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @copyright Copyright 2003-2006, Point Clark Networks
 */

class WebServices extends Engine
{
	///////////////////////////////////////////////////////////////////////////////
	// M E M B E R S
	///////////////////////////////////////////////////////////////////////////////

	protected $service;
	protected $cachefile;
	protected $config = array();
	protected $is_loaded = false;
	protected $hostkey = "";
	protected $langcode = "en_US";
	protected $vendor = "";

	const CONSTANT_UNKNOWN = 'unknown';
	const CONSTANT_UNLIMITED = 'unlimited';
	const CONSTANT_INCLUDED = 'included';
	const CONSTANT_EXTRA = 'extra';
	const CONSTANT_ASP = 'asp';
	const CONSTANT_NOT_REGISTERED = 20;
	const PATH_SUBSCRIPTIONS = '/var/lib/system/services';
	const FILE_REGISTERED = '/usr/share/system/modules/services/registered';
	const FILE_CONFIG = '/usr/share/system/modules/services/environment';

	///////////////////////////////////////////////////////////////////////////////
	// M E T H O D S
	///////////////////////////////////////////////////////////////////////////////

	/**
	 * The WebServices constructor.
	 *
	 * The constructor requires the name of the remote service, for example:
	 *
	 *  - DynamicDNS - Dynamic DNS service
	 *  - IpReferrer - IP Referrer service
	 *  - Ipsec - Managed VPN service
	 *  - Register - System registration service
	 *  - Snort - Intrusion detection rules updates service
	 *  - SoftwareUpdate - Software update service
	 *  - Sophos - Antivirus engine and virus definition service
	 *  - SpamAssassin - Antispam service
	 *
	 * @param string $service service name
	 */

	function __construct($service)
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__construct();

		require_once(GlobalGetLanguageTemplate(__FILE__));

		$this->service = $service;
		$this->cachefile = self::PATH_SUBSCRIPTIONS . "/$service/subscription";
	}


	/**
	 * A generic way to communicate with the Service Delivery Network (SDN).
	 *
	 * You can send IP updates, retrieve software update information, check
	 * dynamic VPN status, etc.  The method will immediately attempt a
	 * connection with alternate servers in the SDN if a previous connection
	 * attempt fails.
	 *
	 * @access private
	 * @param string $action action
	 * @param string $postfields post fields (eg ?ip=1.2.3.4)
	 * @return string payload
	 * @throws EngineException, ValidationException, WebServicesRemoteException
	 */

	public function Request($action, $postfields = "")
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		if (! $this->is_loaded)
			$this->_LoadConfig();

		// The FILE_REGISTERED file is created when a box is successfully
		// registered.  We check to see if this file exists to save the
		// backend from handling endless invalid requests.

		if ($this->service != "Apt") {
			if (! file_exists(self::FILE_REGISTERED))
				throw new WebServicesNotRegisteredException();
		}

		$sdnerror = "";
		$resource = strtolower($this->service) . ".php?action=" . strtolower($action) . $postfields;

		// We always send the following information:
		// - hostkey
		// - vendor (reseller)
		// - language (error messages will be translated one of these days)

		if (!$this->hostkey || !$this->vendor || !$this->langcode)
			$this->LoadDefaultRequestFields();

		$resource .= "&hostkey=" . $this->hostkey . "&vendor=" . $this->vendor . "&lang=" . $this->langcode;

		for ($inx = 1; $inx <= $this->config['sdn_servers']; $inx++) {
			$server = $this->config['sdn_prefix'] . "$inx" . "." . $this->config['sdn_domain'];
			// Logger::Syslog("webservices", "Sending request to SDN $server", "WebServices." . $action);

			if (isset($ch))
				unset($ch);
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, "https://" . $server . "/" . $this->config['sdn_version'] . "/" . $resource);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_HEADER, 0);
			curl_setopt($ch, CURLOPT_TIMEOUT, 20);
			curl_setopt($ch, CURLOPT_FAILONERROR, 1);
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
			$rawmessage = chop(curl_exec($ch));
			$error = curl_error($ch);
			$errno = curl_errno($ch);
			curl_close($ch);

			// Return useful errno messages for the most common errnos
			//--------------------------------------------------------

			if ($errno == 0) {

				//------------------------------------------------------------------
				//
				// Data is ok... return the payload and error message (if any)
				//
				// payload format:
				// exit_code|<code>|<error message>
				// <payload>
				//
				// e.g., a request for dynamic DNS information looks like:
				// exit_code|0|ok
				// 123.12.12.32|1052023323|test.system.net
				//
				//------------------------------------------------------------------

				// Make sure the return data is valid

				if (!preg_match("/exit_code|\d|/", $rawmessage)) {
					$sdnerror = "$server: invalid page or data";
				} else {
					$message = explode("\n", $rawmessage, 2);
					$returned = explode("|", $message[0], 3);

					if (!isset($returned[1])) {
						$sdnerror = "$server: invalid return code";
						$this->Log(COMMON_DEBUG, $sdnerror, "WebServices." . $action, __LINE__);
					} else if ($returned[1] == self::CONSTANT_NOT_REGISTERED) {
						throw new WebServicesNotRegisteredException();
					} else if ($returned[1] != 0) {
						throw new WebServicesRemoteException($returned[2], COMMON_INFO);
					} else {
						// Not all replies have a payload (just true/false)
						if (isset($message[1]))
							return $message[1];
						else
							return "";
					}
				}
			}
		}

		// None of the SDN servers responded -- send the last error code.
		if ($sdnerror)
			throw new EngineException($sdnerror, COMMON_WARNING);
		else if ($errno == CURLE_COULDNT_RESOLVE_HOST)
			throw new EngineException(WEBSERVICES_LANG_ERRMSG_COULDNT_RESOLVE_HOST, COMMON_WARNING);
		else if ($errno == CURLE_OPERATION_TIMEOUTED)
			throw new EngineException(WEBSERVICES_LANG_ERRMSG_TIMEOUT, COMMON_WARNING);
		else
			throw new EngineException(WEBSERVICES_LANG_ERRMSG_CONNECTION_FAIL . " " . $error, COMMON_WARNING);
	}

	/**
	 * Returns subscription status.
	 *
	 * Information in hash array includes:
	 *  - policy
	 *  - expiry
	 *  - license
	 *  - title
	 *  - state
	 *  - status
	 *
	 * @param boolean $realtime set realtime to true to fetch real-time data
	 * @return array information about subscription
	 * @throws EngineException, ValidationException, WebServicesRemoteException
	 */

	public function GetSubscriptionStatus($realtime)
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$file = new File($this->cachefile);
		$fileexists = false;

		try {
			$fileexists = $file->Exists();
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_ERROR);
		}

		if (!$realtime && $fileexists) {
			try {
				$state = $file->LookupValue("/^state\s*=\s*/");
				$isenabled = $file->LookupValue("/^isenabled\s*=\s*/");
				$info["policy"] = $file->LookupValue("/^policy\s*=\s*/");
				$info["expiry"] = $file->LookupValue("/^expiry\s*=\s*/");
				$info["license"] = $file->LookupValue("/^license\s*=\s*/");
				$info["title"] = $file->LookupValue("/^title\s*=\s*/");
				$info["message"] = $file->LookupValue("/^message\s*=\s*/");

				if ($state == "t")
					$info["state"] = true;
				else
					$info["state"] = false;

				if ($isenabled == "t")
					$info["isenabled"] = true;
				else
					$info["isenabled"] = false;

				return $info;
			} catch (Exception $e) {
				throw new EngineException($e->GetMessage(), COMMON_ERROR);
			}
		} else if (!$realtime && !$fileexists) {
			throw new WebServicesNoCacheException();
		}

		// Catch the harmless exceptions -- we do not want them to
		// throw a COMMON_ERROR exception.

		try {
			$payload = $this->Request("GetSubscriptionInfo");
		} catch (WebServicesNotRegisteredException $e) {
			throw new WebServicesNotRegisteredException();
		} catch (WebServicesRemoteException $e) {
			throw new WebServicesRemoteException($e->GetMessage(), COMMON_INFO);
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_ERROR);
		}

		// payload format -- state|policy|expiry|license_type|title|message|state
		$result = explode("|", $payload);

		if ($result[0] == "t")
			$info["state"] = true;
		else
			$info["state"] = false;

		$info["policy"] = $result[1];
		$info["expiry"] = $result[2];
		$info["license"] = $result[3];
		$info["title"] = $result[4];
		$info["message"] = $result[5];

		if ($result[6] == "t")
			$info["isenabled"] = true;
		else
			$info["isenabled"] = false;

		// Cache info
		//-----------

		$folder = new Folder(self::PATH_SUBSCRIPTIONS . "/$this->service");

		try {
			if (! $folder->Exists())
				$folder->Create("suvlet", "suvlet", "0755");

			if ($fileexists)
				$file->Delete();

			$file->Create("suvlet", "suvlet", "0644");
			$file->AddLines(
				"state = $result[0]\n" .
				"policy = $result[1]\n" .
				"expiry = $result[2]\n" .
				"license = $result[3]\n" .
				"title = $result[4]\n" .
				"message = $result[5]\n" .
				"isenabled = $result[6]\n"
			);
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_ERROR);
		}

		return $info;
	}

	/**
	 * Loads default remote request fields.
	 * 
	 * @access private
	 * @return void
	 * @throws EngineException
	 */

	protected function LoadDefaultRequestFields()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		try {
			$suva = new Suva();
			$this->hostkey = $suva->GetHostkey();

			$os = new Os();
			$this->vendor = $os->GetVendorCode();
		
			$language= new Locale();
			$this->langcode = $language->GetLanguageCode();
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_ERROR);
		}
	}
	
	/**
	 * Loads configuration.
	 *
	 * @access private
	 * @return void
	 * @throws EngineException
	 */

	protected function _LoadConfig()
	{
		if (COMMON_DEBUG_MODE)
			self::Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		$configfile = new ConfigurationFile(self::FILE_CONFIG);

		try {
			$this->config = $configfile->Load();
		} catch (Exception $e) {
			throw new EngineException($e->GetMessage(), COMMON_WARNING);
		}

		$this->is_loaded = true;
	}

	/**
	 * @ignore
	 */

	public function __destruct()
	{
		if (COMMON_DEBUG_MODE)
			$this->Log(COMMON_DEBUG, "called", __METHOD__, __LINE__);

		parent::__destruct();
	}
}

// vim: syntax=php ts=4
?>


完!!
2008-8-5 23:29
0
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
wuliao!
2008-8-6 08:15
0
雪    币: 66
活跃值: (835)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4


怎么叫无聊?
2008-8-6 22:24
0
雪    币: 346
活跃值: (1953)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
不错,用php写注册机还可以提高网站流量
2008-8-6 23:50
0
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
本来不太难的东西,写得n页
2008-8-7 10:06
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这个写法有点怪哦 太长了~~~~
但功能觉得很不错
2008-8-7 10:29
0
游客
登录 | 注册 方可回帖
返回
//