diff --git a/apps/files_external/3rdparty/autoload.php b/apps/files_external/3rdparty/autoload.php index 78e3de4ca0..5875a3b996 100644 --- a/apps/files_external/3rdparty/autoload.php +++ b/apps/files_external/3rdparty/autoload.php @@ -2,6 +2,6 @@ // autoload.php @generated by Composer -require_once __DIR__ . '/composer' . '/autoload_real.php'; +require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3::getLoader(); diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json index 158478741e..84f1e19201 100644 --- a/apps/files_external/3rdparty/composer.json +++ b/apps/files_external/3rdparty/composer.json @@ -8,7 +8,7 @@ "classmap-authoritative": true }, "require": { - "icewind/smb": "1.1.0", + "icewind/smb": "2.0.0", "icewind/streams": "0.4.1" } } diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock index 8f324299ff..305cc8dc4b 100644 --- a/apps/files_external/3rdparty/composer.lock +++ b/apps/files_external/3rdparty/composer.lock @@ -4,30 +4,29 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "8ed3150b0b3e916ad66558242b4cf2a0", - "content-hash": "70722dcee13b3ac1c1951479b7431c97", + "hash": "a8b4080027a432533f6d0597ad527fe7", + "content-hash": "8165981792437b03b39c11d28b061eda", "packages": [ { "name": "icewind/smb", - "version": "v1.1.0", + "version": "v2.0.0", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "822f924967c68228555cea84ea44765f8e85c601" + "reference": "95a5ecbaf92617f9800ad7d6070ef31d8ff28c3a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/822f924967c68228555cea84ea44765f8e85c601", - "reference": "822f924967c68228555cea84ea44765f8e85c601", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/95a5ecbaf92617f9800ad7d6070ef31d8ff28c3a", + "reference": "95a5ecbaf92617f9800ad7d6070ef31d8ff28c3a", "shasum": "" }, "require": { "icewind/streams": ">=0.2.0", - "php": ">=5.3" + "php": ">=5.4" }, "require-dev": { - "phpunit/phpunit": "^4.8", - "satooshi/php-coveralls": "v1.0.0" + "phpunit/phpunit": "^4.8" }, "type": "library", "autoload": { @@ -47,7 +46,7 @@ } ], "description": "php wrapper for smbclient and libsmbclient-php", - "time": "2016-04-26 13:26:39" + "time": "2016-12-13 13:56:55" }, { "name": "icewind/streams", diff --git a/apps/files_external/3rdparty/composer/ClassLoader.php b/apps/files_external/3rdparty/composer/ClassLoader.php index ff6ecfb822..ac67d302a1 100644 --- a/apps/files_external/3rdparty/composer/ClassLoader.php +++ b/apps/files_external/3rdparty/composer/ClassLoader.php @@ -53,8 +53,8 @@ class ClassLoader private $useIncludePath = false; private $classMap = array(); - private $classMapAuthoritative = false; + private $missingClasses = array(); public function getPrefixes() { @@ -322,20 +322,20 @@ class ClassLoader if (isset($this->classMap[$class])) { return $this->classMap[$class]; } - if ($this->classMapAuthoritative) { + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { return false; } $file = $this->findFileWithExtension($class, '.php'); // Search for Hack files if we are running on HHVM - if ($file === null && defined('HHVM_VERSION')) { + if (false === $file && defined('HHVM_VERSION')) { $file = $this->findFileWithExtension($class, '.hh'); } - if ($file === null) { + if (false === $file) { // Remember that this class does not exist. - return $this->classMap[$class] = false; + $this->missingClasses[$class] = true; } return $file; @@ -399,6 +399,8 @@ class ClassLoader if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { return $file; } + + return false; } } diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php index 0f9a43c6cd..ba5d06f701 100644 --- a/apps/files_external/3rdparty/composer/autoload_classmap.php +++ b/apps/files_external/3rdparty/composer/autoload_classmap.php @@ -7,6 +7,7 @@ $baseDir = $vendorDir; return array( 'Icewind\\SMB\\AbstractShare' => $vendorDir . '/icewind/smb/src/AbstractShare.php', + 'Icewind\\SMB\\Change' => $vendorDir . '/icewind/smb/src/Change.php', 'Icewind\\SMB\\Connection' => $vendorDir . '/icewind/smb/src/Connection.php', 'Icewind\\SMB\\ErrorCodes' => $vendorDir . '/icewind/smb/src/ErrorCodes.php', 'Icewind\\SMB\\Exception\\AccessDeniedException' => $vendorDir . '/icewind/smb/src/Exception/AccessDeniedException.php', @@ -15,6 +16,7 @@ return array( 'Icewind\\SMB\\Exception\\ConnectException' => $vendorDir . '/icewind/smb/src/Exception/ConnectException.php', 'Icewind\\SMB\\Exception\\ConnectionException' => $vendorDir . '/icewind/smb/src/Exception/ConnectionException.php', 'Icewind\\SMB\\Exception\\ConnectionRefusedException' => $vendorDir . '/icewind/smb/src/Exception/ConnectionRefusedException.php', + 'Icewind\\SMB\\Exception\\DependencyException' => $vendorDir . '/icewind/smb/src/Exception/DependencyException.php', 'Icewind\\SMB\\Exception\\Exception' => $vendorDir . '/icewind/smb/src/Exception/Exception.php', 'Icewind\\SMB\\Exception\\FileInUseException' => $vendorDir . '/icewind/smb/src/Exception/FileInUseException.php', 'Icewind\\SMB\\Exception\\ForbiddenException' => $vendorDir . '/icewind/smb/src/Exception/ForbiddenException.php', @@ -31,17 +33,27 @@ return array( 'Icewind\\SMB\\Exception\\TimedOutException' => $vendorDir . '/icewind/smb/src/Exception/TimedOutException.php', 'Icewind\\SMB\\FileInfo' => $vendorDir . '/icewind/smb/src/FileInfo.php', 'Icewind\\SMB\\IFileInfo' => $vendorDir . '/icewind/smb/src/IFileInfo.php', + 'Icewind\\SMB\\INotifyHandler' => $vendorDir . '/icewind/smb/src/INotifyHandler.php', 'Icewind\\SMB\\IShare' => $vendorDir . '/icewind/smb/src/IShare.php', 'Icewind\\SMB\\NativeFileInfo' => $vendorDir . '/icewind/smb/src/NativeFileInfo.php', 'Icewind\\SMB\\NativeServer' => $vendorDir . '/icewind/smb/src/NativeServer.php', 'Icewind\\SMB\\NativeShare' => $vendorDir . '/icewind/smb/src/NativeShare.php', 'Icewind\\SMB\\NativeState' => $vendorDir . '/icewind/smb/src/NativeState.php', 'Icewind\\SMB\\NativeStream' => $vendorDir . '/icewind/smb/src/NativeStream.php', + 'Icewind\\SMB\\NotifyHandler' => $vendorDir . '/icewind/smb/src/NotifyHandler.php', 'Icewind\\SMB\\Parser' => $vendorDir . '/icewind/smb/src/Parser.php', 'Icewind\\SMB\\RawConnection' => $vendorDir . '/icewind/smb/src/RawConnection.php', 'Icewind\\SMB\\Server' => $vendorDir . '/icewind/smb/src/Server.php', 'Icewind\\SMB\\Share' => $vendorDir . '/icewind/smb/src/Share.php', 'Icewind\\SMB\\System' => $vendorDir . '/icewind/smb/src/System.php', + 'Icewind\\SMB\\Test\\AbstractShare' => $vendorDir . '/icewind/smb/tests/AbstractShare.php', + 'Icewind\\SMB\\Test\\NativeShare' => $vendorDir . '/icewind/smb/tests/NativeShare.php', + 'Icewind\\SMB\\Test\\NativeStream' => $vendorDir . '/icewind/smb/tests/NativeStream.php', + 'Icewind\\SMB\\Test\\NotifyHandlerTest' => $vendorDir . '/icewind/smb/tests/NotifyHandlerTest.php', + 'Icewind\\SMB\\Test\\Parser' => $vendorDir . '/icewind/smb/tests/Parser.php', + 'Icewind\\SMB\\Test\\Server' => $vendorDir . '/icewind/smb/tests/Server.php', + 'Icewind\\SMB\\Test\\Share' => $vendorDir . '/icewind/smb/tests/Share.php', + 'Icewind\\SMB\\Test\\TestCase' => $vendorDir . '/icewind/smb/tests/TestCase.php', 'Icewind\\SMB\\TimeZoneProvider' => $vendorDir . '/icewind/smb/src/TimeZoneProvider.php', 'Icewind\\Streams\\CallbackWrapper' => $vendorDir . '/icewind/streams/src/CallbackWrapper.php', 'Icewind\\Streams\\Directory' => $vendorDir . '/icewind/streams/src/Directory.php', diff --git a/apps/files_external/3rdparty/composer/autoload_real.php b/apps/files_external/3rdparty/composer/autoload_real.php index 6f27fffb9d..4ac68127fe 100644 --- a/apps/files_external/3rdparty/composer/autoload_real.php +++ b/apps/files_external/3rdparty/composer/autoload_real.php @@ -23,9 +23,16 @@ class ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3 self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3', 'loadClassLoader')); - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3::getInitializer($loader)); + } else { + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } } $loader->setClassMapAuthoritative(true); diff --git a/apps/files_external/3rdparty/composer/autoload_static.php b/apps/files_external/3rdparty/composer/autoload_static.php new file mode 100644 index 0000000000..10c09bfc40 --- /dev/null +++ b/apps/files_external/3rdparty/composer/autoload_static.php @@ -0,0 +1,112 @@ + + array ( + 'Icewind\\Streams\\Tests\\' => 22, + 'Icewind\\Streams\\' => 16, + 'Icewind\\SMB\\Test\\' => 17, + 'Icewind\\SMB\\' => 12, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Icewind\\Streams\\Tests\\' => + array ( + 0 => __DIR__ . '/..' . '/icewind/streams/tests', + ), + 'Icewind\\Streams\\' => + array ( + 0 => __DIR__ . '/..' . '/icewind/streams/src', + ), + 'Icewind\\SMB\\Test\\' => + array ( + 0 => __DIR__ . '/..' . '/icewind/smb/tests', + ), + 'Icewind\\SMB\\' => + array ( + 0 => __DIR__ . '/..' . '/icewind/smb/src', + ), + ); + + public static $classMap = array ( + 'Icewind\\SMB\\AbstractShare' => __DIR__ . '/..' . '/icewind/smb/src/AbstractShare.php', + 'Icewind\\SMB\\Change' => __DIR__ . '/..' . '/icewind/smb/src/Change.php', + 'Icewind\\SMB\\Connection' => __DIR__ . '/..' . '/icewind/smb/src/Connection.php', + 'Icewind\\SMB\\ErrorCodes' => __DIR__ . '/..' . '/icewind/smb/src/ErrorCodes.php', + 'Icewind\\SMB\\Exception\\AccessDeniedException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/AccessDeniedException.php', + 'Icewind\\SMB\\Exception\\AlreadyExistsException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/AlreadyExistsException.php', + 'Icewind\\SMB\\Exception\\AuthenticationException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/AuthenticationException.php', + 'Icewind\\SMB\\Exception\\ConnectException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/ConnectException.php', + 'Icewind\\SMB\\Exception\\ConnectionException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/ConnectionException.php', + 'Icewind\\SMB\\Exception\\ConnectionRefusedException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/ConnectionRefusedException.php', + 'Icewind\\SMB\\Exception\\DependencyException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/DependencyException.php', + 'Icewind\\SMB\\Exception\\Exception' => __DIR__ . '/..' . '/icewind/smb/src/Exception/Exception.php', + 'Icewind\\SMB\\Exception\\FileInUseException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/FileInUseException.php', + 'Icewind\\SMB\\Exception\\ForbiddenException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/ForbiddenException.php', + 'Icewind\\SMB\\Exception\\HostDownException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/HostDownException.php', + 'Icewind\\SMB\\Exception\\InvalidHostException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidHostException.php', + 'Icewind\\SMB\\Exception\\InvalidPathException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidPathException.php', + 'Icewind\\SMB\\Exception\\InvalidRequestException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidRequestException.php', + 'Icewind\\SMB\\Exception\\InvalidResourceException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidResourceException.php', + 'Icewind\\SMB\\Exception\\InvalidTypeException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/InvalidTypeException.php', + 'Icewind\\SMB\\Exception\\NoLoginServerException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/NoLoginServerException.php', + 'Icewind\\SMB\\Exception\\NoRouteToHostException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/NoRouteToHostException.php', + 'Icewind\\SMB\\Exception\\NotEmptyException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/NotEmptyException.php', + 'Icewind\\SMB\\Exception\\NotFoundException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/NotFoundException.php', + 'Icewind\\SMB\\Exception\\TimedOutException' => __DIR__ . '/..' . '/icewind/smb/src/Exception/TimedOutException.php', + 'Icewind\\SMB\\FileInfo' => __DIR__ . '/..' . '/icewind/smb/src/FileInfo.php', + 'Icewind\\SMB\\IFileInfo' => __DIR__ . '/..' . '/icewind/smb/src/IFileInfo.php', + 'Icewind\\SMB\\INotifyHandler' => __DIR__ . '/..' . '/icewind/smb/src/INotifyHandler.php', + 'Icewind\\SMB\\IShare' => __DIR__ . '/..' . '/icewind/smb/src/IShare.php', + 'Icewind\\SMB\\NativeFileInfo' => __DIR__ . '/..' . '/icewind/smb/src/NativeFileInfo.php', + 'Icewind\\SMB\\NativeServer' => __DIR__ . '/..' . '/icewind/smb/src/NativeServer.php', + 'Icewind\\SMB\\NativeShare' => __DIR__ . '/..' . '/icewind/smb/src/NativeShare.php', + 'Icewind\\SMB\\NativeState' => __DIR__ . '/..' . '/icewind/smb/src/NativeState.php', + 'Icewind\\SMB\\NativeStream' => __DIR__ . '/..' . '/icewind/smb/src/NativeStream.php', + 'Icewind\\SMB\\NotifyHandler' => __DIR__ . '/..' . '/icewind/smb/src/NotifyHandler.php', + 'Icewind\\SMB\\Parser' => __DIR__ . '/..' . '/icewind/smb/src/Parser.php', + 'Icewind\\SMB\\RawConnection' => __DIR__ . '/..' . '/icewind/smb/src/RawConnection.php', + 'Icewind\\SMB\\Server' => __DIR__ . '/..' . '/icewind/smb/src/Server.php', + 'Icewind\\SMB\\Share' => __DIR__ . '/..' . '/icewind/smb/src/Share.php', + 'Icewind\\SMB\\System' => __DIR__ . '/..' . '/icewind/smb/src/System.php', + 'Icewind\\SMB\\Test\\AbstractShare' => __DIR__ . '/..' . '/icewind/smb/tests/AbstractShare.php', + 'Icewind\\SMB\\Test\\NativeShare' => __DIR__ . '/..' . '/icewind/smb/tests/NativeShare.php', + 'Icewind\\SMB\\Test\\NativeStream' => __DIR__ . '/..' . '/icewind/smb/tests/NativeStream.php', + 'Icewind\\SMB\\Test\\NotifyHandlerTest' => __DIR__ . '/..' . '/icewind/smb/tests/NotifyHandlerTest.php', + 'Icewind\\SMB\\Test\\Parser' => __DIR__ . '/..' . '/icewind/smb/tests/Parser.php', + 'Icewind\\SMB\\Test\\Server' => __DIR__ . '/..' . '/icewind/smb/tests/Server.php', + 'Icewind\\SMB\\Test\\Share' => __DIR__ . '/..' . '/icewind/smb/tests/Share.php', + 'Icewind\\SMB\\Test\\TestCase' => __DIR__ . '/..' . '/icewind/smb/tests/TestCase.php', + 'Icewind\\SMB\\TimeZoneProvider' => __DIR__ . '/..' . '/icewind/smb/src/TimeZoneProvider.php', + 'Icewind\\Streams\\CallbackWrapper' => __DIR__ . '/..' . '/icewind/streams/src/CallbackWrapper.php', + 'Icewind\\Streams\\Directory' => __DIR__ . '/..' . '/icewind/streams/src/Directory.php', + 'Icewind\\Streams\\DirectoryFilter' => __DIR__ . '/..' . '/icewind/streams/src/DirectoryFilter.php', + 'Icewind\\Streams\\DirectoryWrapper' => __DIR__ . '/..' . '/icewind/streams/src/DirectoryWrapper.php', + 'Icewind\\Streams\\File' => __DIR__ . '/..' . '/icewind/streams/src/File.php', + 'Icewind\\Streams\\IteratorDirectory' => __DIR__ . '/..' . '/icewind/streams/src/IteratorDirectory.php', + 'Icewind\\Streams\\NullWrapper' => __DIR__ . '/..' . '/icewind/streams/src/NullWrapper.php', + 'Icewind\\Streams\\Path' => __DIR__ . '/..' . '/icewind/streams/src/Path.php', + 'Icewind\\Streams\\RetryWrapper' => __DIR__ . '/..' . '/icewind/streams/src/RetryWrapper.php', + 'Icewind\\Streams\\SeekableWrapper' => __DIR__ . '/..' . '/icewind/streams/src/SeekableWrapper.php', + 'Icewind\\Streams\\Url' => __DIR__ . '/..' . '/icewind/streams/src/Url.php', + 'Icewind\\Streams\\UrlCallback' => __DIR__ . '/..' . '/icewind/streams/src/UrlCallBack.php', + 'Icewind\\Streams\\Wrapper' => __DIR__ . '/..' . '/icewind/streams/src/Wrapper.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json index 127d2bd3a1..bc71c6d045 100644 --- a/apps/files_external/3rdparty/composer/installed.json +++ b/apps/files_external/3rdparty/composer/installed.json @@ -1,48 +1,4 @@ [ - { - "name": "icewind/smb", - "version": "v1.1.0", - "version_normalized": "1.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/icewind1991/SMB.git", - "reference": "822f924967c68228555cea84ea44765f8e85c601" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/822f924967c68228555cea84ea44765f8e85c601", - "reference": "822f924967c68228555cea84ea44765f8e85c601", - "shasum": "" - }, - "require": { - "icewind/streams": ">=0.2.0", - "php": ">=5.3" - }, - "require-dev": { - "phpunit/phpunit": "^4.8", - "satooshi/php-coveralls": "v1.0.0" - }, - "time": "2016-04-26 13:26:39", - "type": "library", - "installation-source": "source", - "autoload": { - "psr-4": { - "Icewind\\SMB\\": "src/", - "Icewind\\SMB\\Test\\": "tests/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Robin Appelman", - "email": "icewind@owncloud.com" - } - ], - "description": "php wrapper for smbclient and libsmbclient-php" - }, { "name": "icewind/streams", "version": "0.4.1", @@ -85,5 +41,48 @@ } ], "description": "A set of generic stream wrappers" + }, + { + "name": "icewind/smb", + "version": "v2.0.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/icewind1991/SMB.git", + "reference": "95a5ecbaf92617f9800ad7d6070ef31d8ff28c3a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/95a5ecbaf92617f9800ad7d6070ef31d8ff28c3a", + "reference": "95a5ecbaf92617f9800ad7d6070ef31d8ff28c3a", + "shasum": "" + }, + "require": { + "icewind/streams": ">=0.2.0", + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "^4.8" + }, + "time": "2016-12-13 13:56:55", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-4": { + "Icewind\\SMB\\": "src/", + "Icewind\\SMB\\Test\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Robin Appelman", + "email": "icewind@owncloud.com" + } + ], + "description": "php wrapper for smbclient and libsmbclient-php" } ] diff --git a/apps/files_external/3rdparty/icewind/smb/README.md b/apps/files_external/3rdparty/icewind/smb/README.md index 32f3c650f8..c8f31193c8 100644 --- a/apps/files_external/3rdparty/icewind/smb/README.md +++ b/apps/files_external/3rdparty/icewind/smb/README.md @@ -1,7 +1,7 @@ SMB === -[![Coverage Status](https://img.shields.io/coveralls/icewind1991/SMB.svg)](https://coveralls.io/r/icewind1991/SMB?branch=master) +[![Code Coverage](https://scrutinizer-ci.com/g/icewind1991/SMB/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/icewind1991/SMB/?branch=master) [![Build Status](https://travis-ci.org/icewind1991/SMB.svg?branch=master)](https://travis-ci.org/icewind1991/SMB) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/icewind1991/SMB/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/icewind1991/SMB/?branch=master) @@ -134,3 +134,19 @@ if (Server::NativeAvailable()) { $share = $server->getShare('test'); $share->put($fileToUpload, 'example.txt'); ``` + +### Using notify + +```php +getShare('test'); + +$share->notify('')->listen(function (\Icewind\SMB\Change $change) { + echo $change->getCode() . ': ' . $change->getPath() . "\n"; +}); +``` diff --git a/apps/files_external/3rdparty/icewind/smb/composer.json b/apps/files_external/3rdparty/icewind/smb/composer.json index 4ac8b27e72..8374f564bf 100644 --- a/apps/files_external/3rdparty/icewind/smb/composer.json +++ b/apps/files_external/3rdparty/icewind/smb/composer.json @@ -9,11 +9,10 @@ } ], "require" : { - "php": ">=5.3", + "php": ">=5.4", "icewind/streams": ">=0.2.0" }, "require-dev": { - "satooshi/php-coveralls" : "v1.0.0", "phpunit/phpunit": "^4.8" }, "autoload" : { diff --git a/apps/files_external/3rdparty/icewind/smb/src/Connection.php b/apps/files_external/3rdparty/icewind/smb/src/Connection.php index d24cdc1f6d..c1ebb86171 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Connection.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Connection.php @@ -17,6 +17,14 @@ class Connection extends RawConnection { const DELIMITER = 'smb:'; const DELIMITER_LENGTH = 4; + /** @var Parser */ + private $parser; + + public function __construct($command, Parser $parser, $env = array()) { + parent::__construct($command, $env); + $this->parser = $parser; + } + /** * send input to smbclient * @@ -30,7 +38,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 + * @return string[] * @throws AuthenticationException * @throws ConnectException * @throws ConnectionException @@ -42,7 +50,7 @@ class Connection extends RawConnection { throw new ConnectionException('Connection not valid'); } $promptLine = $this->readLine(); //first line is prompt - $this->checkConnectionError($promptLine); + $this->parser->checkConnectionError($promptLine); $output = array(); $line = $this->readLine(); @@ -54,6 +62,7 @@ class Connection extends RawConnection { $result = $callback($line); if ($result === false) { // allow the callback to close the connection for infinite running commands $this->close(true); + break; } } else { $output[] .= $line; @@ -90,33 +99,6 @@ class Connection extends RawConnection { } } - /** - * check if the first line holds a connection failure - * - * @param $line - * @throws AuthenticationException - * @throws InvalidHostException - * @throws NoLoginServerException - */ - private function checkConnectionError($line) { - $line = rtrim($line, ')'); - if (substr($line, -23) === ErrorCodes::LogonFailure) { - throw new AuthenticationException('Invalid login'); - } - if (substr($line, -26) === ErrorCodes::BadHostName) { - throw new InvalidHostException('Invalid hostname'); - } - if (substr($line, -22) === ErrorCodes::Unsuccessful) { - throw new InvalidHostException('Connection unsuccessful'); - } - if (substr($line, -28) === ErrorCodes::ConnectionRefused) { - throw new InvalidHostException('Connection refused'); - } - if (substr($line, -26) === ErrorCodes::NoLogonServers) { - throw new NoLoginServerException('No login server'); - } - } - public function close($terminate = true) { if (is_resource($this->getInputStream())) { $this->write('close' . PHP_EOL); diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php index 3307ad57a2..7ac528198a 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php @@ -7,4 +7,32 @@ namespace Icewind\SMB\Exception; -class Exception extends \Exception {} +class Exception extends \Exception { + static public function unknown($path, $error) { + $message = 'Unknown error (' . $error . ')'; + if ($path) { + $message .= ' for ' . $path; + } + + return new Exception($message, $error); + } + + /** + * @param array $exceptionMap + * @param mixed $error + * @param string $path + * @return Exception + */ + static public function fromMap(array $exceptionMap, $error, $path) { + if (isset($exceptionMap[$error])) { + $exceptionClass = $exceptionMap[$error]; + if (is_numeric($error)) { + return new $exceptionClass($path, $error); + } else { + return new $exceptionClass($path); + } + } else { + return Exception::unknown($path, $error); + } + } +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/IShare.php b/apps/files_external/3rdparty/icewind/smb/src/IShare.php index 4042315133..8f6d5058b8 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/IShare.php +++ b/apps/files_external/3rdparty/icewind/smb/src/IShare.php @@ -8,17 +8,6 @@ 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 * @@ -145,8 +134,7 @@ interface IShare { /** * @param string $path - * @param callable $callback callable which will be called for each received change - * @return mixed + * @return INotifyHandler */ - public function notify($path, callable $callback); + public function notify($path); } diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php b/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php index 6ef5cf0c5b..6cb070196a 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php +++ b/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php @@ -26,7 +26,7 @@ class NativeFileInfo implements IFileInfo { protected $share; /** - * @var array | null + * @var array|null */ protected $statCache; @@ -66,7 +66,7 @@ class NativeFileInfo implements IFileInfo { * @return array */ protected function stat() { - if (!$this->statCache) { + if (is_null($this->statCache)) { $this->statCache = $this->share->getStat($this->getPath()); } return $this->statCache; diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php index 51e16d1841..7efa34df37 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php +++ b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php @@ -60,6 +60,7 @@ class NativeShare extends AbstractShare { } private function buildUrl($path) { + $this->connect(); $this->verifyPath($path); $url = sprintf('smb://%s/%s', $this->server->getHost(), $this->name); if ($path) { @@ -80,7 +81,6 @@ class NativeShare extends AbstractShare { * @throws \Icewind\SMB\Exception\InvalidTypeException */ public function dir($path) { - $this->connect(); $files = array(); $dh = $this->state->opendir($this->buildUrl($path)); @@ -97,14 +97,13 @@ class NativeShare extends AbstractShare { /** * @param string $path - * @return \Icewind\SMB\IFileInfo[] + * @return \Icewind\SMB\IFileInfo */ public function stat($path) { return new NativeFileInfo($this, $path, basename($path), $this->getStat($path)); } public function getStat($path) { - $this->connect(); return $this->state->stat($this->buildUrl($path)); } @@ -118,7 +117,6 @@ class NativeShare extends AbstractShare { * @throws \Icewind\SMB\Exception\AlreadyExistsException */ public function mkdir($path) { - $this->connect(); return $this->state->mkdir($this->buildUrl($path)); } @@ -132,7 +130,6 @@ class NativeShare extends AbstractShare { * @throws \Icewind\SMB\Exception\InvalidTypeException */ public function rmdir($path) { - $this->connect(); return $this->state->rmdir($this->buildUrl($path)); } @@ -146,7 +143,6 @@ class NativeShare extends AbstractShare { * @throws \Icewind\SMB\Exception\InvalidTypeException */ public function del($path) { - $this->connect(); return $this->state->unlink($this->buildUrl($path)); } @@ -161,7 +157,6 @@ class NativeShare extends AbstractShare { * @throws \Icewind\SMB\Exception\AlreadyExistsException */ public function rename($from, $to) { - $this->connect(); return $this->state->rename($this->buildUrl($from), $this->buildUrl($to)); } @@ -176,7 +171,6 @@ class NativeShare extends AbstractShare { * @throws \Icewind\SMB\Exception\InvalidTypeException */ public function put($source, $target) { - $this->connect(); $sourceHandle = fopen($source, 'rb'); $targetHandle = $this->state->create($this->buildUrl($target)); @@ -214,7 +208,6 @@ class NativeShare extends AbstractShare { throw new InvalidResourceException('Failed opening local file "' . $target . '" for writing: ' . $reason); } - $this->connect(); $sourceHandle = $this->state->open($this->buildUrl($source), 'r'); if (!$sourceHandle) { fclose($targetHandle); @@ -238,7 +231,6 @@ class NativeShare extends AbstractShare { * @throws \Icewind\SMB\Exception\InvalidTypeException */ public function read($source) { - $this->connect(); $url = $this->buildUrl($source); $handle = $this->state->open($url, 'r'); return NativeStream::wrap($this->state, $handle, 'r', $url); @@ -254,7 +246,6 @@ class NativeShare extends AbstractShare { * @throws \Icewind\SMB\Exception\InvalidTypeException */ public function write($source) { - $this->connect(); $url = $this->buildUrl($source); $handle = $this->state->create($url); return NativeStream::wrap($this->state, $handle, 'w', $url); @@ -268,10 +259,7 @@ class NativeShare extends AbstractShare { * @return string the attribute value */ public function getAttribute($path, $attribute) { - $this->connect(); - - $result = $this->state->getxattr($this->buildUrl($path), $attribute); - return $result; + return $this->state->getxattr($this->buildUrl($path), $attribute); } /** @@ -283,7 +271,6 @@ class NativeShare extends AbstractShare { * @return string the attribute value */ public function setAttribute($path, $attribute, $value) { - $this->connect(); if ($attribute === 'system.dos_attr.mode' and is_int($value)) { $value = '0x' . dechex($value); @@ -303,14 +290,13 @@ class NativeShare extends AbstractShare { /** * @param string $path - * @param callable $callback callable which will be called for each received change - * @return mixed + * @return INotifyHandler */ - public function notify($path, callable $callback) { + public function notify($path) { // 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); + return $share->notify($path); } public function __destruct() { diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeState.php b/apps/files_external/3rdparty/icewind/smb/src/NativeState.php index e3e344d9e0..7ddce83185 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/NativeState.php +++ b/apps/files_external/3rdparty/icewind/smb/src/NativeState.php @@ -7,16 +7,7 @@ namespace Icewind\SMB; -use Icewind\SMB\Exception\AlreadyExistsException; -use Icewind\SMB\Exception\ConnectionRefusedException; use Icewind\SMB\Exception\Exception; -use Icewind\SMB\Exception\ForbiddenException; -use Icewind\SMB\Exception\HostDownException; -use Icewind\SMB\Exception\InvalidTypeException; -use Icewind\SMB\Exception\NoRouteToHostException; -use Icewind\SMB\Exception\NotEmptyException; -use Icewind\SMB\Exception\NotFoundException; -use Icewind\SMB\Exception\TimedOutException; /** * Low level wrapper for libsmbclient-php for error handling @@ -31,44 +22,39 @@ class NativeState { protected $connected = false; + // todo replace with static once <5.6 support is dropped + // see error.h + private static $exceptionMap = [ + 1 => '\Icewind\SMB\Exception\ForbiddenException', + 2 => '\Icewind\SMB\Exception\NotFoundException', + 13 => '\Icewind\SMB\Exception\ForbiddenException', + 17 => '\Icewind\SMB\Exception\AlreadyExistsException', + 20 => '\Icewind\SMB\Exception\InvalidTypeException', + 21 => '\Icewind\SMB\Exception\InvalidTypeException', + 39 => '\Icewind\SMB\Exception\NotEmptyException', + 110 => '\Icewind\SMB\Exception\TimedOutException', + 111 => '\Icewind\SMB\Exception\ConnectionRefusedException', + 112 => '\Icewind\SMB\Exception\HostDownException', + 113 => '\Icewind\SMB\Exception\NoRouteToHostException' + ]; + protected function handleError($path) { $error = smbclient_state_errno($this->state); - switch ($error) { - // see error.h - case 0; - return; - case 1: - case 13: - throw new ForbiddenException($path, $error); - case 2: - throw new NotFoundException($path, $error); - case 17: - throw new AlreadyExistsException($path, $error); - case 20: - throw new InvalidTypeException($path, $error); - case 21: - throw new InvalidTypeException($path, $error); - case 39: - throw new NotEmptyException($path, $error); - case 110: - throw new TimedOutException($path, $error); - case 111: - throw new ConnectionRefusedException($path, $error); - case 112: - throw new HostDownException($path, $error); - case 113: - throw new NoRouteToHostException($path, $error); - default: - $message = 'Unknown error (' . $error . ')'; - if ($path) { - $message .= ' for ' . $path; - } - throw new Exception($message, $error); + if ($error === 0) { + return; } + throw Exception::fromMap(self::$exceptionMap, $error, $path); } - protected function testResult($result, $path) { + protected function testResult($result, $uri) { if ($result === false or $result === null) { + // smb://host/share/path + if (is_string($uri)) { + list(, , , , $path) = explode('/', $uri, 5); + $path = '/' . $path; + } else { + $path = null; + } $this->handleError($path); } } @@ -246,7 +232,7 @@ class NativeState { * @param resource $file * @param int $offset * @param int $whence SEEK_SET | SEEK_CUR | SEEK_END - * @return int | bool new file offset as measured from the start of the file on success, false on failure. + * @return int|bool new file offset as measured from the start of the file on success, false on failure. */ public function lseek($file, $offset, $whence = SEEK_SET) { $result = @smbclient_lseek($this->state, $file, $offset, $whence); diff --git a/apps/files_external/3rdparty/icewind/smb/src/Parser.php b/apps/files_external/3rdparty/icewind/smb/src/Parser.php index fc1d7f283a..5cc5acbdf5 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Parser.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Parser.php @@ -9,19 +9,38 @@ namespace Icewind\SMB; use Icewind\SMB\Exception\AccessDeniedException; use Icewind\SMB\Exception\AlreadyExistsException; +use Icewind\SMB\Exception\AuthenticationException; use Icewind\SMB\Exception\Exception; use Icewind\SMB\Exception\FileInUseException; +use Icewind\SMB\Exception\InvalidHostException; use Icewind\SMB\Exception\InvalidResourceException; use Icewind\SMB\Exception\InvalidTypeException; +use Icewind\SMB\Exception\NoLoginServerException; use Icewind\SMB\Exception\NotEmptyException; use Icewind\SMB\Exception\NotFoundException; class Parser { + const MSG_NOT_FOUND = 'Error opening local file '; + /** * @var \Icewind\SMB\TimeZoneProvider */ protected $timeZoneProvider; + // todo replace with static once <5.6 support is dropped + // see error.h + private static $exceptionMap = [ + ErrorCodes::PathNotFound => '\Icewind\SMB\Exception\NotFoundException', + ErrorCodes::ObjectNotFound => '\Icewind\SMB\Exception\NotFoundException', + ErrorCodes::NoSuchFile => '\Icewind\SMB\Exception\NotFoundException', + ErrorCodes::NameCollision => '\Icewind\SMB\Exception\AlreadyExistsException', + ErrorCodes::AccessDenied => '\Icewind\SMB\Exception\AccessDeniedException', + ErrorCodes::DirectoryNotEmpty => '\Icewind\SMB\Exception\NotEmptyException', + ErrorCodes::FileIsADirectory => '\Icewind\SMB\Exception\InvalidTypeException', + ErrorCodes::NotADirectory => '\Icewind\SMB\Exception\InvalidTypeException', + ErrorCodes::SharingViolation => '\Icewind\SMB\Exception\FileInUseException' + ]; + /** * @param \Icewind\SMB\TimeZoneProvider $timeZoneProvider */ @@ -29,50 +48,54 @@ class Parser { $this->timeZoneProvider = $timeZoneProvider; } + private function getErrorCode($line) { + $parts = explode(' ', $line); + foreach ($parts as $part) { + if (substr($part, 0, 9) === 'NT_STATUS') { + return $part; + } + } + return false; + } + public function checkForError($output, $path) { - if (count($output) === 0) { - return true; - } else { - if (strpos($output[0], 'does not exist')) { - throw new NotFoundException($path); - } - $parts = explode(' ', $output[0]); - $error = false; - foreach ($parts as $part) { - if (substr($part, 0, 9) === 'NT_STATUS') { - $error = $part; - } - } + if (strpos($output[0], 'does not exist')) { + throw new NotFoundException($path); + } + $error = $this->getErrorCode($output[0]); - $notFoundMsg = 'Error opening local file '; - if (substr($output[0], 0, strlen($notFoundMsg)) === $notFoundMsg) { - $localPath = substr($output[0], strlen($notFoundMsg)); - throw new InvalidResourceException('Failed opening local file "' . $localPath . '" for writing'); - } + if (substr($output[0], 0, strlen(self::MSG_NOT_FOUND)) === self::MSG_NOT_FOUND) { + $localPath = substr($output[0], strlen(self::MSG_NOT_FOUND)); + throw new InvalidResourceException('Failed opening local file "' . $localPath . '" for writing'); + } - switch ($error) { - case ErrorCodes::PathNotFound: - case ErrorCodes::ObjectNotFound: - case ErrorCodes::NoSuchFile: - throw new NotFoundException($path); - case ErrorCodes::NameCollision: - throw new AlreadyExistsException($path); - case ErrorCodes::AccessDenied: - throw new AccessDeniedException($path); - case ErrorCodes::DirectoryNotEmpty: - throw new NotEmptyException($path); - case ErrorCodes::FileIsADirectory: - case ErrorCodes::NotADirectory: - throw new InvalidTypeException($path); - case ErrorCodes::SharingViolation: - throw new FileInUseException($path); - default: - $message = 'Unknown error (' . $error . ')'; - if ($path) { - $message .= ' for ' . $path; - } - throw new Exception($message); - } + throw Exception::fromMap(self::$exceptionMap, $error, $path); + } + + /** + * check if the first line holds a connection failure + * + * @param $line + * @throws AuthenticationException + * @throws InvalidHostException + * @throws NoLoginServerException + */ + public function checkConnectionError($line) { + $line = rtrim($line, ')'); + if (substr($line, -23) === ErrorCodes::LogonFailure) { + throw new AuthenticationException('Invalid login'); + } + if (substr($line, -26) === ErrorCodes::BadHostName) { + throw new InvalidHostException('Invalid hostname'); + } + if (substr($line, -22) === ErrorCodes::Unsuccessful) { + throw new InvalidHostException('Connection unsuccessful'); + } + if (substr($line, -28) === ErrorCodes::ConnectionRefused) { + throw new InvalidHostException('Connection refused'); + } + if (substr($line, -26) === ErrorCodes::NoLogonServers) { + throw new NoLoginServerException('No login server'); } } @@ -95,9 +118,7 @@ class Parser { } public function parseStat($output) { - $mtime = 0; - $mode = 0; - $size = 0; + $data = []; foreach ($output as $line) { // A line = explode statement may not fill all array elements // properly. May happen when accessing non Windows Fileservers @@ -105,20 +126,13 @@ class Parser { $name = isset($words[0]) ? $words[0] : ''; $value = isset($words[1]) ? $words[1] : ''; $value = trim($value); - if ($name === 'write_time') { - $mtime = strtotime($value); - } else if ($name === 'attributes') { - $mode = hexdec(substr($value, 1, -1)); - } else if ($name === 'stream') { - list(, $size,) = explode(' ', $value); - $size = intval($size); - } + $data[$name] = $value; } - return array( - 'mtime' => $mtime, - 'mode' => $mode, - 'size' => $size - ); + return [ + 'mtime' => strtotime($data['write_time']), + 'mode' => hexdec(substr($data['attributes'], strpos($data['attributes'], '('), -1)), + 'size' => isset($data['stream']) ? intval(explode(' ', $data['stream'])[1]) : 0 + ]; } public function parseDir($output, $basePath) { @@ -139,4 +153,17 @@ class Parser { } return $content; } + + public function parseListShares($output) { + $shareNames = array(); + foreach ($output as $line) { + if (strpos($line, '|')) { + list($type, $name, $description) = explode('|', $line); + if (strtolower($type) === 'disk') { + $shareNames[$name] = $description; + } + } + } + return $shareNames; + } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php b/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php index 88ab046ef3..e934971643 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php +++ b/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php @@ -88,7 +88,7 @@ class RawConnection { /** * read a line of output * - * @return string + * @return string|false */ public function readLine() { return stream_get_line($this->getOutputStream(), 4086, "\n"); diff --git a/apps/files_external/3rdparty/icewind/smb/src/Server.php b/apps/files_external/3rdparty/icewind/smb/src/Server.php index 25f1720139..12692eb4c6 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Server.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Server.php @@ -135,32 +135,11 @@ class Server { $connection = new RawConnection($command); $connection->writeAuthentication($this->getUser(), $this->getPassword()); $output = $connection->readAll(); + $parser = new Parser($this->timezoneProvider); - $line = $output[0]; + $parser->checkConnectionError($output[0]); - $line = rtrim($line, ')'); - if (substr($line, -23) === ErrorCodes::LogonFailure) { - throw new AuthenticationException(); - } - if (substr($line, -26) === ErrorCodes::BadHostName) { - throw new InvalidHostException(); - } - if (substr($line, -22) === ErrorCodes::Unsuccessful) { - throw new InvalidHostException(); - } - if (substr($line, -28) === ErrorCodes::ConnectionRefused) { - throw new InvalidHostException(); - } - - $shareNames = array(); - foreach ($output as $line) { - if (strpos($line, '|')) { - list($type, $name, $description) = explode('|', $line); - if (strtolower($type) === 'disk') { - $shareNames[$name] = $description; - } - } - } + $shareNames = $parser->parseListShares($output); $shares = array(); foreach ($shareNames as $name => $description) { @@ -174,7 +153,7 @@ class Server { * @return \Icewind\SMB\IShare */ public function getShare($name) { - return new Share($this, $name); + return new Share($this, $name, $this->system); } /** diff --git a/apps/files_external/3rdparty/icewind/smb/src/Share.php b/apps/files_external/3rdparty/icewind/smb/src/Share.php index 21f8fe5b13..ba8bbbbb8c 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Share.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Share.php @@ -8,6 +8,7 @@ namespace Icewind\SMB; use Icewind\SMB\Exception\ConnectionException; +use Icewind\SMB\Exception\DependencyException; use Icewind\SMB\Exception\FileInUseException; use Icewind\SMB\Exception\InvalidTypeException; use Icewind\SMB\Exception\NotFoundException; @@ -42,24 +43,30 @@ class Share extends AbstractShare { /** * @param Server $server * @param string $name + * @param System $system */ - public function __construct($server, $name) { + public function __construct($server, $name, System $system = null) { parent::__construct(); $this->server = $server; $this->name = $name; - $this->system = new System(); + $this->system = (!is_null($system)) ? $system : new System(); $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', + $smbClientPath = $this->system->getSmbclientPath(); + if (!$smbClientPath) { + throw new DependencyException('Can\'t find smbclient binary in path'); + } + $command = sprintf('%s%s %s --authentication-file=%s %s', + $this->system->hasStdBuf() ? 'stdbuf -o0 ' : '', $this->system->getSmbclientPath(), $workgroupArgument, System::getFD(3), escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) ); - $connection = new Connection($command); + $connection = new Connection($command, $this->parser); $connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); if (!$connection->isValid()) { throw new ConnectionException(); @@ -97,8 +104,8 @@ class Share extends AbstractShare { } protected function simpleCommand($command, $path) { - $path = $this->escapePath($path); - $cmd = $command . ' ' . $path; + $escapedPath = $this->escapePath($path); + $cmd = $command . ' ' . $escapedPath; $output = $this->execute($cmd); return $this->parseOutput($output, $path); } @@ -125,7 +132,7 @@ class Share extends AbstractShare { /** * @param string $path - * @return \Icewind\SMB\IFileInfo[] + * @return \Icewind\SMB\IFileInfo */ public function stat($path) { $escapedPath = $this->escapePath($path); @@ -216,8 +223,7 @@ class Share extends AbstractShare { public function rename($from, $to) { $path1 = $this->escapePath($from); $path2 = $this->escapePath($to); - $cmd = 'rename ' . $path1 . ' ' . $path2; - $output = $this->execute($cmd); + $output = $this->execute('rename ' . $path1 . ' ' . $path2); return $this->parseOutput($output, $to); } @@ -268,15 +274,8 @@ class Share extends AbstractShare { $source = $this->escapePath($source); // 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 - $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) - ); - $connection = new Connection($command); - $connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); + $connection = $this->getConnection(); + $connection->write('get ' . $source . ' ' . System::getFD(5)); $connection->write('exit'); $fh = $connection->getFileOutputStream(); @@ -297,17 +296,9 @@ class Share extends AbstractShare { $target = $this->escapePath($target); // 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 - $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) - ); - $connection = new Connection($command); - $connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); - $fh = $connection->getFileInputStream(); + $connection = $this->getConnection(); + $fh = $connection->getFileInputStream(); $connection->write('put ' . System::getFD(4) . ' ' . $target); $connection->write('exit'); @@ -343,30 +334,30 @@ class Share extends AbstractShare { $output = $this->execute($cmd); $this->parseOutput($output, $path); - // then set the modes we want - $cmd = 'setmode ' . $path . ' ' . $modeString; - $output = $this->execute($cmd); - return $this->parseOutput($output, $path); + if ($mode !== FileInfo::MODE_NORMAL) { + // then set the modes we want + $cmd = 'setmode ' . $path . ' ' . $modeString; + $output = $this->execute($cmd); + return $this->parseOutput($output, $path); + } else { + return true; + } } /** * @param string $path - * @param callable $callback callable which will be called for each received change - * @return mixed + * @return INotifyHandler + * @throws ConnectionException + * @throws DependencyException */ - public function notify($path, callable $callback) { + public function notify($path) { + if (!$this->system->hasStdBuf()) { //stdbuf is required to disable smbclient's output buffering + throw new DependencyException('stdbuf is required for usage of the notify command'); + } $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); - } - }); + return new NotifyHandler($connection, $path); } /** @@ -395,7 +386,12 @@ class Share extends AbstractShare { * @return bool */ protected function parseOutput($lines, $path = '') { - return $this->parser->checkForError($lines, $path); + if (count($lines) === 0) { + return true; + } else { + $this->parser->checkForError($lines, $path); + return false; + } } /** diff --git a/apps/files_external/3rdparty/icewind/smb/src/System.php b/apps/files_external/3rdparty/icewind/smb/src/System.php index 192a0b3877..7c519988aa 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/System.php +++ b/apps/files_external/3rdparty/icewind/smb/src/System.php @@ -14,6 +14,8 @@ class System { private $net; + private $stdbuf; + public static function getFD($num) { $folders = array( '/proc/self/fd', @@ -40,4 +42,14 @@ class System { } return $this->net; } + + public function hasStdBuf() { + if (!$this->stdbuf) { + $result = null; + $output = array(); + exec('which stdbuf 2>&1', $output, $result); + $this->stdbuf = $result === 0; + } + return $this->stdbuf; + } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php b/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php index 86d7859a6f..fcdf7e3e87 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php +++ b/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php @@ -27,7 +27,7 @@ class TimeZoneProvider { * @param string $host * @param System $system */ - function __construct($host, System $system) { + public function __construct($host, System $system) { $this->host = $host; $this->system = $system; } diff --git a/apps/files_external/lib/Lib/Storage/SMB.php b/apps/files_external/lib/Lib/Storage/SMB.php index 4773afcb75..7ffc078df6 100644 --- a/apps/files_external/lib/Lib/Storage/SMB.php +++ b/apps/files_external/lib/Lib/Storage/SMB.php @@ -31,10 +31,12 @@ namespace OCA\Files_External\Lib\Storage; +use Icewind\SMB\Change; use Icewind\SMB\Exception\ConnectException; use Icewind\SMB\Exception\Exception; use Icewind\SMB\Exception\ForbiddenException; use Icewind\SMB\Exception\NotFoundException; +use Icewind\SMB\INotifyHandler; use Icewind\SMB\IFileInfo; use Icewind\SMB\IShare; use Icewind\SMB\NativeServer; @@ -486,16 +488,16 @@ class SMB extends Common implements INotifyStorage { public function listen($path, callable $callback) { $fullPath = $this->buildPath($path); $oldRenamePath = null; - $this->share->notify($fullPath, function ($smbType, $fullPath) use (&$oldRenamePath, $callback) { - $path = $this->relativePath($fullPath); + $this->share->notify($fullPath)->listen(function (Change $change) use (&$oldRenamePath, $callback) { + $path = $this->relativePath($change->getPath()); if (is_null($path)) { return true; } - if ($smbType === IShare::NOTIFY_RENAMED_OLD) { + if ($change->getCode() === INotifyHandler::NOTIFY_RENAMED_OLD) { $oldRenamePath = $path; return true; } - $type = $this->mapNotifyType($smbType); + $type = $this->mapNotifyType($change->getCode()); if (is_null($type)) { return true; } @@ -513,16 +515,16 @@ class SMB extends Common implements INotifyStorage { private function mapNotifyType($smbType) { switch ($smbType) { - case IShare::NOTIFY_ADDED: + case INotifyHandler::NOTIFY_ADDED: return INotifyStorage::NOTIFY_ADDED; - case IShare::NOTIFY_REMOVED: + case INotifyHandler::NOTIFY_REMOVED: return INotifyStorage::NOTIFY_REMOVED; - case IShare::NOTIFY_MODIFIED: - case IShare::NOTIFY_ADDED_STREAM: - case IShare::NOTIFY_MODIFIED_STREAM: - case IShare::NOTIFY_REMOVED_STREAM: + case INotifyHandler::NOTIFY_MODIFIED: + case INotifyHandler::NOTIFY_ADDED_STREAM: + case INotifyHandler::NOTIFY_MODIFIED_STREAM: + case INotifyHandler::NOTIFY_REMOVED_STREAM: return INotifyStorage::NOTIFY_MODIFIED; - case IShare::NOTIFY_RENAMED_NEW: + case INotifyHandler::NOTIFY_RENAMED_NEW: return INotifyStorage::NOTIFY_RENAMED; default: return null;