251 lines
6.9 KiB
PHP
251 lines
6.9 KiB
PHP
<?php
|
|
/**
|
|
* ../overwatch/Ov3rw4tch.class.php
|
|
* Overwatchd
|
|
* @package default
|
|
*/
|
|
|
|
|
|
define("OVERWATCH_ROOT", dirname(__FILE__));
|
|
define("OVERWATCH_LIBRARIES", OVERWATCH_ROOT."/lib");
|
|
define("OVERWATCH_MODULES", OVERWATCH_LIBRARIES."/modules/");
|
|
// Load in module support and required classes.
|
|
require_once "vendor/autoload.php";
|
|
require_once OVERWATCH_LIBRARIES."/libModOverwatch.class.php";
|
|
require_once OVERWATCH_LIBRARIES."/libOverwatchAPI.class.php";
|
|
require_once OVERWATCH_LIBRARIES."/libAPIQL.class.php";
|
|
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)
|
|
$version = file_get_contents(OVERWATCH_ROOT."/build/version");
|
|
|
|
// 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 (or override local) version information using git repository.
|
|
if (file_exists(".git")) {
|
|
$version = `git describe`;
|
|
$application_channel = "dev";
|
|
}
|
|
|
|
// Load the core version from the phar if we're running compiled.
|
|
$coreversion = file_get_contents(OVERWATCH_ROOT."/build/core-version");
|
|
|
|
// Now we'll define the core version of the software as well.
|
|
|
|
$version = str_replace(PHP_EOL, "", $version);
|
|
LogEcho("Overwatchd startup, version: $version (built from: $coreversion), channel: $application_channel", "OVERWATCH");
|
|
|
|
/**
|
|
* Allows a "pretty-print" style output.
|
|
* @param mixed $str Log message.
|
|
* @param mixed $level Log level or specific part of application.
|
|
*/
|
|
function LogEcho($str, $level) {
|
|
$str = str_replace(PHP_EOL, "", $str);
|
|
$level = str_replace(PHP_EOL, "", $level);
|
|
echo "[$level] $str".PHP_EOL;
|
|
}
|
|
|
|
|
|
LogEcho("Loading built-in API Modules...", "OVERWATCH");
|
|
LoadAPIModules(OVERWATCH_MODULES);
|
|
|
|
// 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__."/overwatchd.conf.dist"))
|
|
{
|
|
$configFiles = array(__FILE__."/overwatchd.conf.dist");
|
|
}
|
|
|
|
if(file_exists("/etc/overwatchd.conf"))
|
|
{
|
|
array_push($configFiles,"/etc/overwatchd.conf");
|
|
}
|
|
|
|
if(file_exists(__FILE__."/overwatchd.conf"))
|
|
{
|
|
array_push($configFiles,__FILE__."/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($arrOverwatch_Config['DEBUG'] == "true")
|
|
{
|
|
define("DEBUG",true);
|
|
LogEcho("Enabling debug mode due to configuration flag..", "DEBUG");
|
|
} elseif ($application_channel == "dev")
|
|
{
|
|
define("DEBUG", true);
|
|
LogEcho("We're running under the dev channel. Debug Ahoy!", "DEBUG");
|
|
}
|
|
|
|
}
|
|
|
|
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", "Shutdown");
|
|
$quit == 2;
|
|
} else {
|
|
error_reporting(0);
|
|
}
|
|
|
|
|
|
// 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 ( base64_encode(base64_decode($connection->lastAPI, true)) === $connection->lastAPI){
|
|
if(DEBUG)
|
|
{
|
|
LogEcho("Raw data from conection: $connection->id, $connection->lastAPI","S2S-COMMS-DEBUG");
|
|
}
|
|
|
|
$connection->lastAPI = base64_decode($connection->lastAPI);
|
|
}
|
|
if(strtoupper($connection->lastAPI) != strtoupper("shutdown"))
|
|
{
|
|
$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);
|
|
$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;
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
}
|
|
$connection->lastResult = apicall($connection->lastAPI);
|
|
LogEcho("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");
|
|
|
|
LogEcho("Server listening on port: $API_PORT", "OVERWATCH");
|
|
// Now we begin the actual event loop.
|
|
$loop->run();
|
|
|
|
|
|
/**
|
|
*
|
|
* @return unknown
|
|
*/
|
|
function Shutdown() {
|
|
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;
|
|
}
|
|
return $APIResponse;
|
|
}
|
|
}
|
|
|
|
function LoadModulesFromConfiguration()
|
|
{
|
|
global $arrOverwatch_Config;
|
|
if(array_key_exists("MODULES_DIR", $arrOverwatch_Config))
|
|
{
|
|
LogEcho("External module directory defined, loading external modules...","OVERWATCH");
|
|
LoadAPIModules($arrOverwatch_Config['MODULES_DIR']);
|
|
}
|
|
if(array_key_exists("SYSTEM_MODULES_DIR", $arrOverwatch_Config))
|
|
{
|
|
LogEcho("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);
|
|
}
|
|
|
|
?>
|