← Back
Editing: Passage.php
<?php class PassageMessage { public string $command; public array $args = array(); public array $headers = array(); public ?string $body = null; public function __construct(string $command) { $this->command = $command; } public function serialize(): string { $s = $this->command; if (!empty($this->args)) { $s .= ' '; // TODO quote? $s .= implode(' ', $this->args); } if (!empty($this->headers)) { foreach ($this->headers as $name => $value) { // TODO quote? $s .= "\n$name:$value"; } } if (!is_null($this->body)) { $s .= "\0"; $s .= $this->body; } return $s; } } function cm4all_passage(string|PassageMessage $message): PassageMessage { if (extension_loaded('sockets') === false) throw new ErrorException("The 'sockets' extension is required but missing"); $socket = socket_create(AF_UNIX, SOCK_SEQPACKET, 0); if ($socket === false) throw new RuntimeException("Failed to create socket: " . socket_strerror(socket_last_error())); $socketPath = '/run/cm4all/passage/socket'; $result = socket_connect($socket, $socketPath); if ($result === false) { $error = socket_last_error($socket); socket_close($socket); throw new RuntimeException("Failed to connect to the socket: " . socket_strerror($error)); } if ($message instanceof PassageMessage) $message = $message->serialize(); $bytesSent = socket_send($socket, $message, strlen($message), 0); if ($bytesSent === false) { $error = socket_last_error($socket); socket_close($socket); throw new RuntimeException("Failed to send data: " . socket_strerror($error)); } $response = ''; $bytesReceived = socket_recv($socket, $response, 65536, MSG_WAITALL); if ($bytesReceived === false) { $error = socket_last_error($socket); socket_close($socket); throw new RuntimeException("Failed to receive data: " . socket_strerror($error)); } socket_close($socket); // extract the body (after the null byte) $response = explode("\0", $response, 2); $body = @$response[1]; $response = $response[0]; // extract the first line $response = explode("\n", $response, 2); $line = explode(' ', $response[0], 2); $response = @$response[1]; // extract the command from the first line $msg = new PassageMessage($line[0]); $msg->body = $body; // extract the args from the first line if (@$line[1]) // TDDO allow quoted strings $msg->args = explode(' ', $line[1]); // extract headers from the remaining lines foreach (explode("\n", $response) as $line) { $line = explode(':', $line, 2); if (strlen($line[0]) && isset($line[1])) // TDDO allow quoted strings $msg->headers[$line[0]] = $line[1]; } return $msg; }
Save File
Cancel