mirror of
https://codeberg.org/icewind/SMB.git
synced 2026-06-03 17:24:07 +02:00
split connection code
This commit is contained in:
parent
190ac9501d
commit
59bc57cc06
2 changed files with 107 additions and 60 deletions
|
|
@ -8,66 +8,20 @@
|
||||||
|
|
||||||
namespace SMB;
|
namespace SMB;
|
||||||
|
|
||||||
class Connection {
|
class Connection extends RawConnection {
|
||||||
|
|
||||||
const DELIMITER = 'smb:';
|
const DELIMITER = 'smb:';
|
||||||
|
|
||||||
/**
|
|
||||||
* @var resource[] $pipes
|
|
||||||
*
|
|
||||||
* $pipes[0] holds STDIN for smbclient
|
|
||||||
* $pipes[1] holds STDOUT for smbclient
|
|
||||||
*/
|
|
||||||
private $pipes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var resource $process
|
|
||||||
*/
|
|
||||||
private $process;
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct($command) {
|
|
||||||
$descriptorSpec = array(
|
|
||||||
0 => array("pipe", "r"),
|
|
||||||
1 => array("pipe", "w")
|
|
||||||
);
|
|
||||||
setlocale(LC_ALL, Server::LOCALE);
|
|
||||||
$this->process = proc_open($command, $descriptorSpec, $this->pipes, null, array(
|
|
||||||
'CLI_FORCE_INTERACTIVE' => 'y', // Needed or the prompt isn't displayed!!
|
|
||||||
'LC_ALL' => Server::LOCALE
|
|
||||||
));
|
|
||||||
if (!$this->isValid()) {
|
|
||||||
throw new ConnectionError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if the connection is still active
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isValid() {
|
|
||||||
if (is_resource($this->process)) {
|
|
||||||
$status = proc_get_status($this->process);
|
|
||||||
return $status['running'];
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* send input to smbclient
|
* send input to smbclient
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
*/
|
*/
|
||||||
public function write($input) {
|
public function write($input) {
|
||||||
fwrite($this->pipes[0], $input);
|
parent::write($input . PHP_EOL);
|
||||||
fwrite($this->pipes[0], PHP_EOL); //make sure we have a recognizable delimiter
|
|
||||||
fflush($this->pipes[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get all unprocessed output from smbclient
|
* get all unprocessed output from smbclient untill the next prompt
|
||||||
*
|
*
|
||||||
* @throws ConnectionError
|
* @throws ConnectionError
|
||||||
* @return array
|
* @return array
|
||||||
|
|
@ -76,15 +30,15 @@ class Connection {
|
||||||
if (!$this->isValid()) {
|
if (!$this->isValid()) {
|
||||||
throw new ConnectionError();
|
throw new ConnectionError();
|
||||||
}
|
}
|
||||||
$line = trim(fgets($this->pipes[1])); //first line is prompt
|
$line = parent::read(); //first line is prompt
|
||||||
$this->checkConnectionError($line);
|
$this->checkConnectionError($line);
|
||||||
|
|
||||||
$output = array();
|
$output = array();
|
||||||
$line = fgets($this->pipes[1]);
|
$line = parent::read();
|
||||||
$length = strlen(self::DELIMITER);
|
$length = strlen(self::DELIMITER);
|
||||||
while (substr($line, 0, $length) !== self::DELIMITER) { //next prompt functions as delimiter
|
while (substr($line, 0, $length) !== self::DELIMITER) { //next prompt functions as delimiter
|
||||||
$output[] .= $line;
|
$output[] .= $line;
|
||||||
$line = fgets($this->pipes[1]);
|
$line = parent::read();
|
||||||
}
|
}
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
@ -98,14 +52,16 @@ class Connection {
|
||||||
*/
|
*/
|
||||||
private function checkConnectionError($line) {
|
private function checkConnectionError($line) {
|
||||||
$line = rtrim($line, ')');
|
$line = rtrim($line, ')');
|
||||||
$authError = 'NT_STATUS_LOGON_FAILURE';
|
if (substr($line, -23) === ErrorCodes::LogonFailure) {
|
||||||
if (substr($line, -23) === $authError) {
|
|
||||||
$this->pipes = array(null, null);
|
|
||||||
throw new AuthenticationException();
|
throw new AuthenticationException();
|
||||||
}
|
}
|
||||||
$addressError = 'NT_STATUS_BAD_NETWORK_NAME';
|
if (substr($line, -26) === ErrorCodes::BadHostName) {
|
||||||
if (substr($line, -26) === $addressError) {
|
throw new InvalidHostException();
|
||||||
$this->pipes = array(null, null);
|
}
|
||||||
|
if (substr($line, -22) === ErrorCodes::Unsuccessful) {
|
||||||
|
throw new InvalidHostException();
|
||||||
|
}
|
||||||
|
if (substr($line, -28) === ErrorCodes::ConnectionRefused) {
|
||||||
throw new InvalidHostException();
|
throw new InvalidHostException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +72,6 @@ class Connection {
|
||||||
|
|
||||||
public function __destruct() {
|
public function __destruct() {
|
||||||
$this->close();
|
$this->close();
|
||||||
proc_terminate($this->process);
|
parent::__destruct();
|
||||||
proc_close($this->process);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
92
src/rawconnection.php
Normal file
92
src/rawconnection.php
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later.
|
||||||
|
* See the COPYING-README file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace SMB;
|
||||||
|
|
||||||
|
class RawConnection {
|
||||||
|
/**
|
||||||
|
* @var resource[] $pipes
|
||||||
|
*
|
||||||
|
* $pipes[0] holds STDIN for smbclient
|
||||||
|
* $pipes[1] holds STDOUT for smbclient
|
||||||
|
*/
|
||||||
|
private $pipes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var resource $process
|
||||||
|
*/
|
||||||
|
private $process;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct($command) {
|
||||||
|
$descriptorSpec = array(
|
||||||
|
0 => array("pipe", "r"),
|
||||||
|
1 => array("pipe", "w"),
|
||||||
|
2 => array('file', '/dev/null', 'w')
|
||||||
|
);
|
||||||
|
setlocale(LC_ALL, Server::LOCALE);
|
||||||
|
$this->process = proc_open($command, $descriptorSpec, $this->pipes, null, array(
|
||||||
|
'CLI_FORCE_INTERACTIVE' => 'y', // Needed or the prompt isn't displayed!!
|
||||||
|
'LC_ALL' => Server::LOCALE
|
||||||
|
));
|
||||||
|
if (!$this->isValid()) {
|
||||||
|
throw new ConnectionError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if the connection is still active
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValid() {
|
||||||
|
if (is_resource($this->process)) {
|
||||||
|
$status = proc_get_status($this->process);
|
||||||
|
return $status['running'];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send input to the process
|
||||||
|
*
|
||||||
|
* @param string $input
|
||||||
|
*/
|
||||||
|
public function write($input) {
|
||||||
|
fwrite($this->pipes[0], $input);
|
||||||
|
fflush($this->pipes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read a line of output
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function read() {
|
||||||
|
return trim(fgets($this->pipes[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all output until the process closes
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function readAll() {
|
||||||
|
$output = array();
|
||||||
|
while ($line = $this->read()) {
|
||||||
|
$output[] = $line;
|
||||||
|
}
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
proc_terminate($this->process);
|
||||||
|
proc_close($this->process);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue