275 lines
8.0 KiB
PHP
275 lines
8.0 KiB
PHP
<?php
|
|
/**
|
|
* ../overwatch/Ov3rw4tch.class.php
|
|
* Overwatchd
|
|
* @package default
|
|
*/
|
|
|
|
|
|
define("OVERWATCH_ROOT", dirname(__FILE__));
|
|
define("OVERWATCH_LIBRARIES", OVERWATCH_ROOT.DIRECTORY_SEPARATOR."lib");
|
|
define("OVERWATCH_MODULES", OVERWATCH_LIBRARIES.DIRECTORY_SEPARATOR."modules".DIRECTORY_SEPARATOR);
|
|
// Load in module support and required classes.
|
|
require_once "vendor/autoload.php";
|
|
require_once OVERWATCH_LIBRARIES.DIRECTORY_SEPARATOR."libModOverwatch.class.php";
|
|
require_once OVERWATCH_LIBRARIES.DIRECTORY_SEPARATOR."libOverwatchAPI.class.php";
|
|
require_once OVERWATCH_LIBRARIES.DIRECTORY_SEPARATOR."libAPIQL.class.php";
|
|
require_once OVERWATCH_ROOT.DIRECTORY_SEPARATOR."sdk".DIRECTORY_SEPARATOR."OverwatchSDK.inc.php";
|
|
if(\Overwatch\SDK\Manager::isSDK_Installed("1") == false)
|
|
{
|
|
die("OverwatchSDK is missing, possibly a bad build, or tree?");
|
|
}
|
|
use Noodlehaus\Config;
|
|
echo PHP_EOL;
|
|
|
|
#error_reporting(0);
|
|
$quit = 0;
|
|
$arrOverwatch_Config = array();
|
|
$arrOverwatch_SystemConfig = array();
|
|
$application_channel = "release";
|
|
|
|
|
|
|
|
// Load version information from built-in version file. (used for releases)
|
|
if(file_exists(OVERWATCH_ROOT.DIRECTORY_SEPARATOR."build".DIRECTORY_SEPARATOR."version"))
|
|
{
|
|
$version = file_get_contents(OVERWATCH_ROOT.DIRECTORY_SEPARATOR."build".DIRECTORY_SEPARATOR."version");
|
|
}
|
|
|
|
|
|
// Load (or override local) version information using git repository.
|
|
if (file_exists(".git")) {
|
|
$version = `git describe`;
|
|
$application_channel = "dev";
|
|
}
|
|
|
|
// Define engine version so that plugins can check against it.
|
|
// We will want to define the local version information (built into the phar if compiled)
|
|
// rather than the git version, unless there's a decent way to compare versions provided by git describe.
|
|
define("OVERWATCH_VERSION", $version);
|
|
|
|
|
|
// Load the core version from the phar if we're running compiled.
|
|
if(file_exists(OVERWATCH_ROOT.DIRECTORY_SEPARATOR."build".DIRECTORY_SEPARATOR."core-version"))
|
|
{
|
|
$coreversion = file_get_contents(OVERWATCH_ROOT.DIRECTORY_SEPARATOR."build".DIRECTORY_SEPARATOR."core-version");
|
|
} else {
|
|
$coreversion = $version;
|
|
}
|
|
|
|
|
|
// Now we'll define the core version of the software as well.
|
|
|
|
$coreversion = str_replace(array("\n", "\r"), "", $coreversion);
|
|
$version = str_replace(array("\n", "\r"), "", $version);
|
|
\Overwatch\SDK\v1\Utility::Log("Overwatchd startup, version: $version (built from: $coreversion), channel: $application_channel", "OVERWATCH");
|
|
|
|
|
|
|
|
// We look for a system-wide configuration file for the daemon in /etc. If one is not available,
|
|
// we then skip it.
|
|
if(file_exists(__FILE__.DIRECTORY_SEPARATOR."overwatchd.conf.dist"))
|
|
{
|
|
$configFiles = array(__FILE__.DIRECTORY_SEPARATOR."overwatchd.conf.dist");
|
|
}
|
|
|
|
if(file_exists("/etc/overwatchd.conf"))
|
|
{
|
|
array_push($configFiles,"/etc/overwatchd.conf");
|
|
}
|
|
|
|
if(file_exists(__FILE__.DIRECTORY_SEPARATOR."overwatchd.conf"))
|
|
{
|
|
array_push($configFiles,__FILE__.DIRECTOR_SEPARATOR."overwatchd.conf");
|
|
}
|
|
|
|
if(isset($configFiles))
|
|
{
|
|
$arrOverwatch_Config = new Config($configFiles);
|
|
}
|
|
|
|
|
|
// We're now looking for a local configuration file for the daemon.
|
|
// Allow turning on debug mode from a configuration option.
|
|
|
|
if(array_key_exists("DEBUG",$arrOverwatch_Config) OR $application_channel == "dev")
|
|
{
|
|
if(array_key_exists("DEBUG", $arrOverwatch_Config) AND $arrOverwatch_Config['DEBUG'] == "true")
|
|
{
|
|
define("DEBUG",true);
|
|
\Overwatch\SDK\v1\Utility::Log("Enabling debug mode due to configuration flag..", "DEBUG");
|
|
} elseif ($application_channel == "dev")
|
|
{
|
|
define("DEBUG", true);
|
|
\Overwatch\SDK\v1\Utility::Log("We're running under the dev channel. Debug Ahoy!", "DEBUG");
|
|
}
|
|
|
|
}
|
|
\Overwatch\SDK\v1\Utility::Log("Loading built-in API Modules...", "OVERWATCH");
|
|
LoadAPIModules(OVERWATCH_MODULES);
|
|
|
|
LoadModulesFromConfiguration();
|
|
$state = array();
|
|
|
|
// We're going to register a shutdown command so that we can easily shutdown the system remotely,
|
|
// only when we're in debug mode though. We'll also turn on PHP's error messages.
|
|
if(defined("DEBUG"))
|
|
{
|
|
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
|
|
apiql::register("!SHUTDOWN[json]", "Shutdown");
|
|
$quit == 2;
|
|
} else {
|
|
error_reporting(0);
|
|
}
|
|
|
|
function is_base64($str) {
|
|
|
|
if (!preg_match('~[^0-9a-zA-Z+/=]~', $str)) {
|
|
|
|
$check = str_split(base64_decode($str));
|
|
|
|
$x = 0;
|
|
|
|
foreach ($check as $char) if (ord($char) > 126) $x++;
|
|
|
|
if ($x/count($check)*100 < 30) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// Let's set up the event loop
|
|
$loop = React\EventLoop\Factory::create();
|
|
|
|
// Now that the rest is set up, let's start the actual server.
|
|
$socket = new React\Socket\Server($loop);
|
|
$clients = new SplObjectStorage();
|
|
$i = 0;
|
|
$socket->on('connection', function($connection) use ($clients, &$i) {
|
|
$connection->id = ++$i;
|
|
|
|
// Socket Listener
|
|
$connection->on('data', function($message) use ($clients, $connection) {
|
|
$connection->lastAPI = str_replace(array("\n", "\r\n", "\r"), '', $message);
|
|
if(strpos($connection->lastAPI, " {") == 0)
|
|
{
|
|
if (is_base64($connection->lastAPI) == true) {
|
|
\Overwatch\SDK\v1\Utility::Log("Raw data from conection: $connection->id, $connection->lastAPI","S2S-COMMS-DEBUG",\Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
|
$connection->lastAPI = base64_decode($connection->lastAPI);
|
|
}
|
|
}
|
|
|
|
$connection->lastAPI = str_replace("'", "\"", $connection->lastAPI);
|
|
# Let's pull apart the current request to check for a connection-id item. If it doesn't exist, we'll inject it in.
|
|
$command = explode (" {", $connection->lastAPI, 2);
|
|
if(isset($command[1]))
|
|
{
|
|
$commandJSON = json_decode("{".$command[1], true);
|
|
}
|
|
if(!isset($commandJSON['connection-id']))
|
|
{
|
|
$commandJSON['connection-id'] = $connection->id;
|
|
$commandJSON = json_encode($commandJSON);
|
|
$connection->lastAPI = rtrim($command[0]," ")." ".$commandJSON;
|
|
}
|
|
|
|
|
|
$connection->lastResult = apicall($connection->lastAPI);
|
|
\Overwatch\SDK\v1\Utility::Log("Received query: ".$connection->lastAPI." from ".$connection->id, "SOCKET-API");
|
|
foreach ($clients as $client) {
|
|
if ($client->id == $connection->id) {
|
|
if($connection->lastResult != NULL)
|
|
{
|
|
$client->write($connection->lastResult."\r\n");
|
|
}
|
|
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
});
|
|
$clients->attach($connection);
|
|
});
|
|
|
|
if (empty($arrOverwatch_Config['API_PORT'])) {
|
|
$API_PORT="1337";
|
|
} else {
|
|
$API_PORT= $arrOverwatch_Config['API_PORT'];
|
|
}
|
|
// Start listening on the configured port.
|
|
$socket->listen($API_PORT, "0.0.0.0");
|
|
|
|
\Overwatch\SDK\v1\Utility::Log("Server listening on port: $API_PORT", "OVERWATCH");
|
|
// Now we begin the actual event loop.
|
|
$loop->run();
|
|
|
|
|
|
/**
|
|
*
|
|
* @return unknown
|
|
*/
|
|
function Shutdown($sql) {
|
|
global $quit;
|
|
global $loop;
|
|
$loop->stop();
|
|
$quit = 1;
|
|
return "Shutting Down.";
|
|
exit(0);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param unknown $call
|
|
* @param unknown $apiKey (optional)
|
|
* @return unknown
|
|
*/
|
|
function APIcall($call, $apiKey = null) {
|
|
|
|
#LogEcho("APIcall($call)","S2S-DEBUG");
|
|
|
|
$APIResponse = apiql::query($call);
|
|
if ($APIResponse == NULL) {
|
|
$ResponseArray = array('response_type'=>"error",
|
|
'response_data'=>array('type'=>'APIcall',
|
|
'data'=>$call,
|
|
'response'=>$APIResponse),
|
|
'response_code'=>'OVW_404');
|
|
return "ERROR ".json_encode($ResponseArray);
|
|
} else {
|
|
if(empty($APIResponse) or $APIResponse == "1")
|
|
{
|
|
return NULL;
|
|
}
|
|
if(is_array($APIResponse))
|
|
{
|
|
$APIResponse = json_encode($APIResponse);
|
|
}
|
|
return $APIResponse;
|
|
}
|
|
}
|
|
|
|
function LoadModulesFromConfiguration()
|
|
{
|
|
global $arrOverwatch_Config;
|
|
if(array_key_exists("MODULES_DIR", $arrOverwatch_Config))
|
|
{
|
|
\Overwatch\SDK\v1\Utility::Log("External module directory defined, loading external modules...","OVERWATCH");
|
|
LoadAPIModules($arrOverwatch_Config['MODULES_DIR']);
|
|
}
|
|
if(array_key_exists("SYSTEM_MODULES_DIR", $arrOverwatch_Config))
|
|
{
|
|
\Overwatch\SDK\v1\Utility::Log("Loading modules from system store: ".$arrOverwatch_Config['SYSTEM_MODULES_DIR']);
|
|
LoadAPIModules($arrOverwatch_Config['SYSTEM_MODULES_DIR']);
|
|
}
|
|
}
|
|
|
|
function is_json($json)
|
|
{
|
|
json_decode($json);
|
|
return (json_last_error() == JSON_ERROR_NONE);
|
|
}
|
|
|
|
?>
|