|
|
@ -7,17 +7,13 @@ |
|
|
|
|
|
|
|
|
namespace Icewind\SMB; |
|
|
namespace Icewind\SMB; |
|
|
|
|
|
|
|
|
use Icewind\SMB\Exception\AccessDeniedException; |
|
|
|
|
|
use Icewind\SMB\Exception\AlreadyExistsException; |
|
|
|
|
|
use Icewind\SMB\Exception\ConnectionException; |
|
|
use Icewind\SMB\Exception\ConnectionException; |
|
|
use Icewind\SMB\Exception\Exception; |
|
|
|
|
|
use Icewind\SMB\Exception\FileInUseException; |
|
|
use Icewind\SMB\Exception\FileInUseException; |
|
|
use Icewind\SMB\Exception\InvalidTypeException; |
|
|
use Icewind\SMB\Exception\InvalidTypeException; |
|
|
use Icewind\SMB\Exception\NotEmptyException; |
|
|
|
|
|
use Icewind\SMB\Exception\NotFoundException; |
|
|
use Icewind\SMB\Exception\NotFoundException; |
|
|
use Icewind\Streams\CallbackWrapper; |
|
|
use Icewind\Streams\CallbackWrapper; |
|
|
|
|
|
|
|
|
class Share implements IShare { |
|
|
|
|
|
|
|
|
class Share extends AbstractShare { |
|
|
/** |
|
|
/** |
|
|
* @var Server $server |
|
|
* @var Server $server |
|
|
*/ |
|
|
*/ |
|
|
@ -43,6 +39,7 @@ class Share implements IShare { |
|
|
* @param string $name |
|
|
* @param string $name |
|
|
*/ |
|
|
*/ |
|
|
public function __construct($server, $name) { |
|
|
public function __construct($server, $name) { |
|
|
|
|
|
parent::__construct(); |
|
|
$this->server = $server; |
|
|
$this->server = $server; |
|
|
$this->name = $name; |
|
|
$this->name = $name; |
|
|
$this->parser = new Parser(new TimeZoneProvider($this->server->getHost())); |
|
|
$this->parser = new Parser(new TimeZoneProvider($this->server->getHost())); |
|
|
@ -58,11 +55,10 @@ class Share implements IShare { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; |
|
|
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; |
|
|
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 //%s/%s', |
|
|
|
|
|
|
|
|
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s', |
|
|
Server::CLIENT, |
|
|
Server::CLIENT, |
|
|
$workgroupArgument, |
|
|
$workgroupArgument, |
|
|
$this->server->getHost(), |
|
|
|
|
|
$this->name |
|
|
|
|
|
|
|
|
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) |
|
|
); |
|
|
); |
|
|
$this->connection = new Connection($command); |
|
|
$this->connection = new Connection($command); |
|
|
$this->connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); |
|
|
$this->connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); |
|
|
@ -258,20 +254,18 @@ class Share implements IShare { |
|
|
*/ |
|
|
*/ |
|
|
public function read($source) { |
|
|
public function read($source) { |
|
|
$source = $this->escapePath($source); |
|
|
$source = $this->escapePath($source); |
|
|
// close the single quote, open a double quote where we put the single quote...
|
|
|
|
|
|
$source = str_replace('\'', '\'"\'"\'', $source); |
|
|
|
|
|
// since returned stream is closed by the caller we need to create a new instance
|
|
|
// since returned stream is closed by the caller we need to create a new instance
|
|
|
// since we can't re-use the same file descriptor over multiple calls
|
|
|
// since we can't re-use the same file descriptor over multiple calls
|
|
|
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; |
|
|
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; |
|
|
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 //%s/%s -c \'get %s /proc/self/fd/5\'', |
|
|
|
|
|
|
|
|
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s', |
|
|
Server::CLIENT, |
|
|
Server::CLIENT, |
|
|
$workgroupArgument, |
|
|
$workgroupArgument, |
|
|
$this->server->getHost(), |
|
|
|
|
|
$this->name, |
|
|
|
|
|
$source |
|
|
|
|
|
|
|
|
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) |
|
|
); |
|
|
); |
|
|
$connection = new Connection($command); |
|
|
$connection = new Connection($command); |
|
|
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); |
|
|
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); |
|
|
|
|
|
$connection->write('get ' . $source . ' /proc/self/fd/5'); |
|
|
|
|
|
$connection->write('exit'); |
|
|
$fh = $connection->getFileOutputStream(); |
|
|
$fh = $connection->getFileOutputStream(); |
|
|
stream_context_set_option($fh, 'file', 'connection', $connection); |
|
|
stream_context_set_option($fh, 'file', 'connection', $connection); |
|
|
return $fh; |
|
|
return $fh; |
|
|
@ -288,25 +282,24 @@ class Share implements IShare { |
|
|
*/ |
|
|
*/ |
|
|
public function write($target) { |
|
|
public function write($target) { |
|
|
$target = $this->escapePath($target); |
|
|
$target = $this->escapePath($target); |
|
|
// close the single quote, open a double quote where we put the single quote...
|
|
|
|
|
|
$target = str_replace('\'', '\'"\'"\'', $target); |
|
|
|
|
|
// since returned stream is closed by the caller we need to create a new instance
|
|
|
// since returned stream is closed by the caller we need to create a new instance
|
|
|
// since we can't re-use the same file descriptor over multiple calls
|
|
|
// since we can't re-use the same file descriptor over multiple calls
|
|
|
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; |
|
|
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; |
|
|
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 //%s/%s -c \'put /proc/self/fd/4 %s\'', |
|
|
|
|
|
|
|
|
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s', |
|
|
Server::CLIENT, |
|
|
Server::CLIENT, |
|
|
$workgroupArgument, |
|
|
$workgroupArgument, |
|
|
$this->server->getHost(), |
|
|
|
|
|
$this->name, |
|
|
|
|
|
$target |
|
|
|
|
|
|
|
|
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) |
|
|
); |
|
|
); |
|
|
$connection = new RawConnection($command); |
|
|
|
|
|
|
|
|
$connection = new Connection($command); |
|
|
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); |
|
|
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); |
|
|
$fh = $connection->getFileInputStream(); |
|
|
$fh = $connection->getFileInputStream(); |
|
|
|
|
|
|
|
|
|
|
|
$connection->write('put /proc/self/fd/4 ' . $target); |
|
|
|
|
|
$connection->write('exit'); |
|
|
|
|
|
|
|
|
// use a close callback to ensure the upload is finished before continuing
|
|
|
// use a close callback to ensure the upload is finished before continuing
|
|
|
// this also serves as a way to keep the connection in scope
|
|
|
// this also serves as a way to keep the connection in scope
|
|
|
return CallbackWrapper::wrap($fh, null, null, function () use ($connection) { |
|
|
|
|
|
|
|
|
return CallbackWrapper::wrap($fh, null, null, function () use ($connection, $target) { |
|
|
$connection->close(false); // dont terminate, give the upload some time
|
|
|
$connection->close(false); // dont terminate, give the upload some time
|
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
@ -384,6 +377,7 @@ class Share implements IShare { |
|
|
* @return string |
|
|
* @return string |
|
|
*/ |
|
|
*/ |
|
|
protected function escapePath($path) { |
|
|
protected function escapePath($path) { |
|
|
|
|
|
$this->verifyPath($path); |
|
|
if ($path === '/') { |
|
|
if ($path === '/') { |
|
|
$path = ''; |
|
|
$path = ''; |
|
|
} |
|
|
} |
|
|
|