HEX
Server: Apache/2.4.67 (Debian)
System: Linux hosting103 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
User: muzikaecom (1013)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: //usr/local/share/hostingplatform/esrpc.php
<?php

class ESRPCConnection {
    public $proc;
    public $out;
    public $in;
    public $target = NULL;
    public $requestid = 1;
    public $debug = 0;

    public function connect($cmd=NULL) {
	if($cmd) {
	    $this->debug = (
            isset($_ENV["ESRPC_DEBUG"])
                ? true == $_ENV["ESRPC_DEBUG"]
                : false
        );
	    $descriptorspec = array(
		0 => array("pipe", "r"),
		1 => array("pipe", "w"),
		2 => array("file", "php://stderr", "w")
	    );
	    $this->proc = proc_open($cmd, $descriptorspec, $pipes);
	    if(!$this->proc) {
		throw new ESRPCProtocolException('Failed to open connection');
	    }
	    $this->in = $pipes[1];
	    $this->out = $pipes[0];
	    if (!$this->ping()) {
		throw new ESRPCProtocolException('Failed to ping');
	    }
	} else {
	    $this->in = STDIN;
	    $this->out = STDOUT;
	}
    }

    public function close() {
	fclose($this->out);
	fread($this->in, 1);
	proc_close($this->proc);
    }

    public function get() {
	return new ESRPCRemoteObject($this);
    }

    public function setTarget($target) {
	$this->target = $target;
    }

    public function call($method, $arguments) {
	$request = array(
	    "id" => "x" . $this->requestid++,
	    "method" => $method,
	    "params" => $arguments
	);
	$this->write_message($request);
	for(;;) {
	    if (!$this->read_message($message)) break;
	    if(array_key_exists("result", $message)) {
		return $message["result"];
	    } else if(array_key_exists("error", $message)) {
		$e = new ESRPCRemoteException($message["error"]["message"]);
		if($message["error"]["longmessage"]) {
		    $e->setLongMessage($message["error"]["longmessage"]);
		}
		throw $e;
	    } else {
		$this->handle_request($message);
	    }
	}
    }

    public function ping() {
	$request = array(
	    "id" => "x" . $this->requestid++,
	    "ping" => 1
	);
	$this->write_message($request);
	for(;;) {
	    if (!$this->read_message($message)) break;

	    if(
		array_key_exists("pong", $message) 
		&& $message['id'] == $request['id'] 
		&& $message['pong'] == $request['ping']
	    ) {
		return true;
	    } else {
		$this->handle_request($message);
	    }
	}

	return false;
    }

    public function serve() {
	try {
	    while($this->read_message($request)) {
		$this->handle_request($request);
	    }
	} catch (Exception $e) {
	    $response = array(
		"error" => array(
		    "message" => $e->getMessage(),
		    "longmessage" => $e->getMessage() . "\n" .
			$e->getTraceAsString()));
	    $this->write_message($response);
	}
    }

    public function handle_request($request) {
	$response = array("id" => $request["id"]);
	if(array_key_exists("ping", $request)) {
	    $response["pong"] = $request["ping"];
	} else if(array_key_exists("method", $request)) {
	    if(!$this->target) {
		throw new ESRPCProtocolException('No call target set');
	    }
	    try {
		$response["result"] = call_user_func_array(
		    array($this->target, $request["method"]),
		    $request["params"]);
	    } catch (Exception $e) {
		$response["error"] = array(
		    "message" => $e->getMessage(),
		    "longmessage" => $e->getMessage() . "\n" .
		$e->getTraceAsString());
	    }
	} else {
	    throw new ESRPCProtocolException('Unhandled message received');
	}
	$this->write_message($response);
    }

    public function write_message($message) {
	if($this->debug) {
	    fwrite(STDERR, " >>> " . json_encode($message) . "\n");
	}
	$message_data = json_encode($message);
	if(!fwrite($this->out, sprintf("%08X", strlen($message_data)))) {
	    throw new ESRPCProtocolException('Failed to send message length');
	}
	if(!fwrite($this->out, $message_data)) {
	    throw new ESRPCProtocolException('Failed to send message body');
	}
    }

    public function read_message(&$message) {
	$message = NULL;
	$message_length = fread($this->in, 8);
	if($message_length === false) {
	    throw new ESRPCProtocolException(
		'Failed to read ESRPC message: read error in length');
	} if(strlen($message_length) == 0) {
	    return FALSE;
	} else if(strlen($message_length) != 8) {
	    throw new ESRPCProtocolException(
		'Failed to read ESRPC message: unexpected EOF in length');
	}
	if(!preg_match("/^[0-9a-fA-F]{8}$/", $message_length)) {
	    throw new ESRPCProtocolException(
		'Illegal message length: ' . $message_length);
	}
	$message_length = hexdec($message_length);
	$message_data = "";
	while(strlen($message_data) < $message_length) {
	    $buf = fread($this->in, $message_length - strlen($message_data));
	    if($buf === false) {
		throw new ESRPCProtocolException(
		    'Failed to read ESRPC message: read error in body');
	    } else if (strlen($buf) < 1) {
		throw new ESRPCProtocolException(
		    'Failed to read ESRPC message: Unexpected EOF in body');
	    }
	    $message_data .= $buf;
	}
	$message = json_decode($message_data, TRUE);

	if(!is_array($message) || !isset($message['id'])) {
	    throw new ESRPCProtocolException('Invalid message received: ' . $message_data);
	}

	if($this->debug) {
	    fwrite(STDERR, " <<< " . json_encode($message) . "\n");
	}
	return TRUE;
    }
}

class ESRPCRemoteObject {
    public $connection;

    public function __construct($connection) {
	$this->connection = $connection;
    }

    public function __call($method, $arguments) {
	return $this->connection->call($method, $arguments);
    }
}

class ESRPCProtocolException extends Exception {}

class ESRPCRemoteException extends Exception {
    public $longmessage = NULL;

    public function setLongMessage($message) {
	$this->longmessage = $message;
    }

    public function getLongMessage() {
	if($this->longmessage) {
	    return $this->longmessage;
	} else {
	    return $this->getMessage();
	}
    }
}