diff options
author | Robin Appelman <icewind@owncloud.com> | 2016-04-26 15:43:30 +0200 |
---|---|---|
committer | Robin Appelman <icewind@owncloud.com> | 2016-04-26 15:43:30 +0200 |
commit | 1cc17436f794d19f92be9330f86057103448d01c (patch) | |
tree | 24d18aefbd0ea1e09d686208f22586ad5063e3f4 /apps/files_external/3rdparty/icewind | |
parent | 14c34919774484d095d26ad2a7246fc897dc2d41 (diff) | |
download | nextcloud-server-1cc17436f794d19f92be9330f86057103448d01c.tar.gz nextcloud-server-1cc17436f794d19f92be9330f86057103448d01c.zip |
update icewind/streams to 1.1.0
Diffstat (limited to 'apps/files_external/3rdparty/icewind')
4 files changed, 107 insertions, 26 deletions
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Connection.php b/apps/files_external/3rdparty/icewind/smb/src/Connection.php index f48dcb766e4..d24cdc1f6d0 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Connection.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Connection.php @@ -15,6 +15,7 @@ use Icewind\SMB\Exception\NoLoginServerException; class Connection extends RawConnection { const DELIMITER = 'smb:'; + const DELIMITER_LENGTH = 4; /** * send input to smbclient @@ -28,6 +29,7 @@ class Connection extends RawConnection { /** * get all unprocessed output from smbclient until the next prompt * + * @param callable $callback (optional) callback to call for every line read * @return string * @throws AuthenticationException * @throws ConnectException @@ -35,7 +37,7 @@ class Connection extends RawConnection { * @throws InvalidHostException * @throws NoLoginServerException */ - public function read() { + public function read(callable $callback = null) { if (!$this->isValid()) { throw new ConnectionException('Connection not valid'); } @@ -45,26 +47,50 @@ class Connection extends RawConnection { $output = array(); $line = $this->readLine(); if ($line === false) { - if ($promptLine) { //maybe we have some error we missed on the previous line - throw new ConnectException('Unknown error (' . $promptLine . ')'); - } else { - $error = $this->readError(); // maybe something on stderr - if ($error) { - throw new ConnectException('Unknown error (' . $error . ')'); - } else { - throw new ConnectException('Unknown error'); + $this->unknownError($promptLine); + } + while (!$this->isPrompt($line)) { //next prompt functions as delimiter + if (is_callable($callback)) { + $result = $callback($line); + if ($result === false) { // allow the callback to close the connection for infinite running commands + $this->close(true); } + } else { + $output[] .= $line; } - } - $length = mb_strlen(self::DELIMITER); - while (mb_substr($line, 0, $length) !== self::DELIMITER) { //next prompt functions as delimiter - $output[] .= $line; $line = $this->readLine(); } return $output; } /** + * Check + * + * @param $line + * @return bool + */ + private function isPrompt($line) { + return mb_substr($line, 0, self::DELIMITER_LENGTH) === self::DELIMITER || $line === false; + } + + /** + * @param string $promptLine (optional) prompt line that might contain some info about the error + * @throws ConnectException + */ + private function unknownError($promptLine = '') { + if ($promptLine) { //maybe we have some error we missed on the previous line + throw new ConnectException('Unknown error (' . $promptLine . ')'); + } else { + $error = $this->readError(); // maybe something on stderr + if ($error) { + throw new ConnectException('Unknown error (' . $error . ')'); + } else { + throw new ConnectException('Unknown error'); + } + } + } + + /** * check if the first line holds a connection failure * * @param $line diff --git a/apps/files_external/3rdparty/icewind/smb/src/IShare.php b/apps/files_external/3rdparty/icewind/smb/src/IShare.php index 4851e9de053..40423151332 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/IShare.php +++ b/apps/files_external/3rdparty/icewind/smb/src/IShare.php @@ -8,6 +8,17 @@ namespace Icewind\SMB; interface IShare { + // https://msdn.microsoft.com/en-us/library/dn392331.aspx + const NOTIFY_ADDED = 1; + const NOTIFY_REMOVED = 2; + const NOTIFY_MODIFIED = 3; + const NOTIFY_RENAMED_OLD = 4; + const NOTIFY_RENAMED_NEW = 5; + const NOTIFY_ADDED_STREAM = 6; + const NOTIFY_REMOVED_STREAM = 7; + const NOTIFY_MODIFIED_STREAM = 8; + const NOTIFY_REMOVED_BY_DELETE = 9; + /** * Get the name of the share * @@ -131,4 +142,11 @@ interface IShare { * @return mixed */ public function setMode($path, $mode); + + /** + * @param string $path + * @param callable $callback callable which will be called for each received change + * @return mixed + */ + public function notify($path, callable $callback); } diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php index 27d975514a3..51e16d1841f 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php +++ b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php @@ -301,6 +301,18 @@ class NativeShare extends AbstractShare { return $this->setAttribute($path, 'system.dos_attr.mode', $mode); } + /** + * @param string $path + * @param callable $callback callable which will be called for each received change + * @return mixed + */ + public function notify($path, callable $callback) { + // php-smbclient does support notify (https://github.com/eduardok/libsmbclient-php/issues/29) + // so we use the smbclient based backend for this + $share = new Share($this->server, $this->getName()); + $share->notify($path, $callback); + } + public function __destruct() { unset($this->state); } diff --git a/apps/files_external/3rdparty/icewind/smb/src/Share.php b/apps/files_external/3rdparty/icewind/smb/src/Share.php index 694bd30bd0d..21f8fe5b139 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Share.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Share.php @@ -51,6 +51,22 @@ class Share extends AbstractShare { $this->parser = new Parser(new TimeZoneProvider($this->server->getHost(), $this->system)); } + protected function getConnection() { + $workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; + $command = sprintf('stdbuf -o0 %s %s --authentication-file=%s %s', + $this->system->getSmbclientPath(), + $workgroupArgument, + System::getFD(3), + escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) + ); + $connection = new Connection($command); + $connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); + if (!$connection->isValid()) { + throw new ConnectionException(); + } + return $connection; + } + /** * @throws \Icewind\SMB\Exception\ConnectionException * @throws \Icewind\SMB\Exception\AuthenticationException @@ -60,18 +76,7 @@ class Share extends AbstractShare { if ($this->connection and $this->connection->isValid()) { return; } - $workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; - $command = sprintf('%s %s --authentication-file=%s %s', - $this->system->getSmbclientPath(), - $workgroupArgument, - System::getFD(3), - escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) - ); - $this->connection = new Connection($command); - $this->connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); - if (!$this->connection->isValid()) { - throw new ConnectionException(); - } + $this->connection = $this->getConnection(); } protected function reconnect() { @@ -345,6 +350,26 @@ class Share extends AbstractShare { } /** + * @param string $path + * @param callable $callback callable which will be called for each received change + * @return mixed + */ + public function notify($path, callable $callback) { + $connection = $this->getConnection(); // use a fresh connection since the notify command blocks the process + $command = 'notify ' . $this->escapePath($path); + $connection->write($command . PHP_EOL); + $connection->read(function ($line) use ($callback, $path) { + $code = (int)substr($line, 0, 4); + $subPath = substr($line, 5); + if ($path === '') { + return $callback($code, $subPath); + } else { + return $callback($code, $path . '/' . $subPath); + } + }); + } + + /** * @param string $command * @return array */ @@ -370,7 +395,7 @@ class Share extends AbstractShare { * @return bool */ protected function parseOutput($lines, $path = '') { - $this->parser->checkForError($lines, $path); + return $this->parser->checkForError($lines, $path); } /** |