diff --git a/apps/files_external/3rdparty/.gitignore b/apps/files_external/3rdparty/.gitignore index ce8b521ff5..5eae814c79 100644 --- a/apps/files_external/3rdparty/.gitignore +++ b/apps/files_external/3rdparty/.gitignore @@ -1,4 +1,5 @@ example.php +.editorconfig icewind/smb/tests icewind/smb/install_libsmbclient.sh icewind/smb/Makefile diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json index caf87983c5..20e4b8a4d3 100644 --- a/apps/files_external/3rdparty/composer.json +++ b/apps/files_external/3rdparty/composer.json @@ -9,6 +9,6 @@ }, "require": { "icewind/streams": "0.6.1", - "icewind/smb": "3.0.0" + "icewind/smb": "3.1.0" } } diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock index 2339220ffb..33c975a7d7 100644 --- a/apps/files_external/3rdparty/composer.lock +++ b/apps/files_external/3rdparty/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1465c8a4b4139e514086d5803d90af2d", + "content-hash": "ea11a8c6e4979d35dd3bdf1f057ef0e8", "packages": [ { "name": "icewind/smb", - "version": "v3.0.0", + "version": "v3.1.0", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "0d31da4757a37d322e1e181f2286e8a4c89fbc0c" + "reference": "db16d4430cb75f0196eaa6377c5766b19f744c8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/0d31da4757a37d322e1e181f2286e8a4c89fbc0c", - "reference": "0d31da4757a37d322e1e181f2286e8a4c89fbc0c", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/db16d4430cb75f0196eaa6377c5766b19f744c8d", + "reference": "db16d4430cb75f0196eaa6377c5766b19f744c8d", "shasum": "" }, "require": { @@ -25,6 +25,7 @@ "php": ">=5.6" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^2.13", "phpunit/phpunit": "^5.7" }, "type": "library", @@ -45,7 +46,7 @@ } ], "description": "php wrapper for smbclient and libsmbclient-php", - "time": "2018-05-24T09:48:51+00:00" + "time": "2019-02-06T14:17:35+00:00" }, { "name": "icewind/streams", diff --git a/apps/files_external/3rdparty/composer/ClassLoader.php b/apps/files_external/3rdparty/composer/ClassLoader.php index dc02dfb114..fce8549f07 100644 --- a/apps/files_external/3rdparty/composer/ClassLoader.php +++ b/apps/files_external/3rdparty/composer/ClassLoader.php @@ -279,7 +279,7 @@ class ClassLoader */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** @@ -377,7 +377,7 @@ class ClassLoader $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php index 6c5f86a579..b92bd22b4f 100644 --- a/apps/files_external/3rdparty/composer/autoload_classmap.php +++ b/apps/files_external/3rdparty/composer/autoload_classmap.php @@ -39,8 +39,11 @@ return array( 'Icewind\\SMB\\IAuth' => $vendorDir . '/icewind/smb/src/IAuth.php', 'Icewind\\SMB\\IFileInfo' => $vendorDir . '/icewind/smb/src/IFileInfo.php', 'Icewind\\SMB\\INotifyHandler' => $vendorDir . '/icewind/smb/src/INotifyHandler.php', + 'Icewind\\SMB\\IOptions' => $vendorDir . '/icewind/smb/src/IOptions.php', 'Icewind\\SMB\\IServer' => $vendorDir . '/icewind/smb/src/IServer.php', 'Icewind\\SMB\\IShare' => $vendorDir . '/icewind/smb/src/IShare.php', + 'Icewind\\SMB\\ISystem' => $vendorDir . '/icewind/smb/src/ISystem.php', + 'Icewind\\SMB\\ITimeZoneProvider' => $vendorDir . '/icewind/smb/src/ITimeZoneProvider.php', 'Icewind\\SMB\\KerberosAuth' => $vendorDir . '/icewind/smb/src/KerberosAuth.php', 'Icewind\\SMB\\Native\\NativeFileInfo' => $vendorDir . '/icewind/smb/src/Native/NativeFileInfo.php', 'Icewind\\SMB\\Native\\NativeReadStream' => $vendorDir . '/icewind/smb/src/Native/NativeReadStream.php', @@ -49,6 +52,7 @@ return array( 'Icewind\\SMB\\Native\\NativeState' => $vendorDir . '/icewind/smb/src/Native/NativeState.php', 'Icewind\\SMB\\Native\\NativeStream' => $vendorDir . '/icewind/smb/src/Native/NativeStream.php', 'Icewind\\SMB\\Native\\NativeWriteStream' => $vendorDir . '/icewind/smb/src/Native/NativeWriteStream.php', + 'Icewind\\SMB\\Options' => $vendorDir . '/icewind/smb/src/Options.php', 'Icewind\\SMB\\ServerFactory' => $vendorDir . '/icewind/smb/src/ServerFactory.php', 'Icewind\\SMB\\System' => $vendorDir . '/icewind/smb/src/System.php', 'Icewind\\SMB\\TimeZoneProvider' => $vendorDir . '/icewind/smb/src/TimeZoneProvider.php', diff --git a/apps/files_external/3rdparty/composer/autoload_static.php b/apps/files_external/3rdparty/composer/autoload_static.php index 658c947c9c..6d7ed9d853 100644 --- a/apps/files_external/3rdparty/composer/autoload_static.php +++ b/apps/files_external/3rdparty/composer/autoload_static.php @@ -69,8 +69,11 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Icewind\\SMB\\IAuth' => __DIR__ . '/..' . '/icewind/smb/src/IAuth.php', 'Icewind\\SMB\\IFileInfo' => __DIR__ . '/..' . '/icewind/smb/src/IFileInfo.php', 'Icewind\\SMB\\INotifyHandler' => __DIR__ . '/..' . '/icewind/smb/src/INotifyHandler.php', + 'Icewind\\SMB\\IOptions' => __DIR__ . '/..' . '/icewind/smb/src/IOptions.php', 'Icewind\\SMB\\IServer' => __DIR__ . '/..' . '/icewind/smb/src/IServer.php', 'Icewind\\SMB\\IShare' => __DIR__ . '/..' . '/icewind/smb/src/IShare.php', + 'Icewind\\SMB\\ISystem' => __DIR__ . '/..' . '/icewind/smb/src/ISystem.php', + 'Icewind\\SMB\\ITimeZoneProvider' => __DIR__ . '/..' . '/icewind/smb/src/ITimeZoneProvider.php', 'Icewind\\SMB\\KerberosAuth' => __DIR__ . '/..' . '/icewind/smb/src/KerberosAuth.php', 'Icewind\\SMB\\Native\\NativeFileInfo' => __DIR__ . '/..' . '/icewind/smb/src/Native/NativeFileInfo.php', 'Icewind\\SMB\\Native\\NativeReadStream' => __DIR__ . '/..' . '/icewind/smb/src/Native/NativeReadStream.php', @@ -79,6 +82,7 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Icewind\\SMB\\Native\\NativeState' => __DIR__ . '/..' . '/icewind/smb/src/Native/NativeState.php', 'Icewind\\SMB\\Native\\NativeStream' => __DIR__ . '/..' . '/icewind/smb/src/Native/NativeStream.php', 'Icewind\\SMB\\Native\\NativeWriteStream' => __DIR__ . '/..' . '/icewind/smb/src/Native/NativeWriteStream.php', + 'Icewind\\SMB\\Options' => __DIR__ . '/..' . '/icewind/smb/src/Options.php', 'Icewind\\SMB\\ServerFactory' => __DIR__ . '/..' . '/icewind/smb/src/ServerFactory.php', 'Icewind\\SMB\\System' => __DIR__ . '/..' . '/icewind/smb/src/System.php', 'Icewind\\SMB\\TimeZoneProvider' => __DIR__ . '/..' . '/icewind/smb/src/TimeZoneProvider.php', diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json index 707b876e58..ff95369926 100644 --- a/apps/files_external/3rdparty/composer/installed.json +++ b/apps/files_external/3rdparty/composer/installed.json @@ -1,17 +1,17 @@ [ { "name": "icewind/smb", - "version": "v3.0.0", - "version_normalized": "3.0.0.0", + "version": "v3.1.0", + "version_normalized": "3.1.0.0", "source": { "type": "git", "url": "https://github.com/icewind1991/SMB.git", - "reference": "0d31da4757a37d322e1e181f2286e8a4c89fbc0c" + "reference": "db16d4430cb75f0196eaa6377c5766b19f744c8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/icewind1991/SMB/zipball/0d31da4757a37d322e1e181f2286e8a4c89fbc0c", - "reference": "0d31da4757a37d322e1e181f2286e8a4c89fbc0c", + "url": "https://api.github.com/repos/icewind1991/SMB/zipball/db16d4430cb75f0196eaa6377c5766b19f744c8d", + "reference": "db16d4430cb75f0196eaa6377c5766b19f744c8d", "shasum": "" }, "require": { @@ -19,9 +19,10 @@ "php": ">=5.6" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^2.13", "phpunit/phpunit": "^5.7" }, - "time": "2018-05-24T09:48:51+00:00", + "time": "2019-02-06T14:17:35+00:00", "type": "library", "installation-source": "dist", "autoload": { diff --git a/apps/files_external/3rdparty/icewind/smb/.gitignore b/apps/files_external/3rdparty/icewind/smb/.gitignore index 4f389129e2..966ac1bcbe 100644 --- a/apps/files_external/3rdparty/icewind/smb/.gitignore +++ b/apps/files_external/3rdparty/icewind/smb/.gitignore @@ -1,3 +1,5 @@ .idea vendor composer.lock +.php_cs.cache + diff --git a/apps/files_external/3rdparty/icewind/smb/.php_cs.dist b/apps/files_external/3rdparty/icewind/smb/.php_cs.dist new file mode 100644 index 0000000000..a2fdf19e80 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/.php_cs.dist @@ -0,0 +1,15 @@ +exclude('vendor') + ->in(__DIR__) +; +return PhpCsFixer\Config::create() + ->setRules([ + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'braces' => ['position_after_functions_and_oop_constructs' => 'same'], + 'binary_operator_spaces' => ['align_double_arrow' => true, 'align_equals' => false], + ]) + ->setIndent("\t") + ->setFinder($finder) + ; diff --git a/apps/files_external/3rdparty/icewind/smb/README.md b/apps/files_external/3rdparty/icewind/smb/README.md index fd47f1a439..4c20b1412a 100644 --- a/apps/files_external/3rdparty/icewind/smb/README.md +++ b/apps/files_external/3rdparty/icewind/smb/README.md @@ -102,6 +102,15 @@ fwrite($fh, 'bar'); fclose($fh); ``` +**Note**: write() will truncate your file to 0bytes. You may open a writeable stream with append() which will point +the cursor to the end of the file or create it if it does not exists yet. (append() is only compatible with libsmbclient-php) +```php +$fh = $share->append('test.txt'); +fwrite($fh, 'bar'); +fclose($fh); +``` + + ### Using notify ```php @@ -110,6 +119,22 @@ $share->notify('')->listen(function (\Icewind\SMB\Change $change) { }); ``` +### Changing network timeouts + +```php +$options = new Options(); +$options->setTimeout(5); +$serverFactory = new ServerFactory($options); +``` + +### Customizing system integration + +The `smbclient` backend needs to get various information about the system it's running on to function +such as the paths of various binaries or the system timezone. +While the default logic for getting this information should work on most systems, it possible to customize this behaviour. + +In order to customize the integration you provide a custom implementation of `ITimezoneProvider` and/or `ISystem` and pass them as arguments to the `ServerFactory`. + ## Testing SMB Use the following steps to check if the library can connect to your SMB share. diff --git a/apps/files_external/3rdparty/icewind/smb/composer.json b/apps/files_external/3rdparty/icewind/smb/composer.json index 708c59bc72..78375c4df4 100644 --- a/apps/files_external/3rdparty/icewind/smb/composer.json +++ b/apps/files_external/3rdparty/icewind/smb/composer.json @@ -13,7 +13,8 @@ "icewind/streams": ">=0.2.0" }, "require-dev": { - "phpunit/phpunit": "^5.7" + "phpunit/phpunit": "^5.7", + "friendsofphp/php-cs-fixer": "^2.13" }, "autoload" : { "psr-4": { diff --git a/apps/files_external/3rdparty/icewind/smb/src/AbstractServer.php b/apps/files_external/3rdparty/icewind/smb/src/AbstractServer.php index 7fa87a5957..aa2adfa67b 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/AbstractServer.php +++ b/apps/files_external/3rdparty/icewind/smb/src/AbstractServer.php @@ -21,7 +21,6 @@ namespace Icewind\SMB; - abstract class AbstractServer implements IServer { const LOCALE = 'en_US.UTF-8'; @@ -36,7 +35,7 @@ abstract class AbstractServer implements IServer { protected $auth; /** - * @var \Icewind\SMB\System + * @var ISystem */ protected $system; @@ -45,41 +44,41 @@ abstract class AbstractServer implements IServer { */ protected $timezoneProvider; + /** @var IOptions */ + protected $options; + /** * @param string $host * @param IAuth $auth - * @param System $system + * @param ISystem $system * @param TimeZoneProvider $timeZoneProvider + * @param IOptions $options */ - public function __construct($host, IAuth $auth, System $system, TimeZoneProvider $timeZoneProvider) { + public function __construct($host, IAuth $auth, ISystem $system, TimeZoneProvider $timeZoneProvider, IOptions $options) { $this->host = $host; $this->auth = $auth; $this->system = $system; $this->timezoneProvider = $timeZoneProvider; + $this->options = $options; } - /** - * @return IAuth - */ public function getAuth() { return $this->auth; } - /** - * return string - */ public function getHost() { return $this->host; } - /** - * @return string - */ public function getTimeZone() { - return $this->timezoneProvider->get(); + return $this->timezoneProvider->get($this->host); } public function getSystem() { return $this->system; } + + public function getOptions() { + return $this->options; + } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/AbstractShare.php b/apps/files_external/3rdparty/icewind/smb/src/AbstractShare.php index 0af03ff569..b53c253be0 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/AbstractShare.php +++ b/apps/files_external/3rdparty/icewind/smb/src/AbstractShare.php @@ -13,7 +13,7 @@ abstract class AbstractShare implements IShare { private $forbiddenCharacters; public function __construct() { - $this->forbiddenCharacters = array('?', '<', '>', ':', '*', '|', '"', chr(0), "\n", "\r"); + $this->forbiddenCharacters = ['?', '<', '>', ':', '*', '|', '"', chr(0), "\n", "\r"]; } protected function verifyPath($path) { diff --git a/apps/files_external/3rdparty/icewind/smb/src/AnonymousAuth.php b/apps/files_external/3rdparty/icewind/smb/src/AnonymousAuth.php index 6d1feacf1e..737cc7c63f 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/AnonymousAuth.php +++ b/apps/files_external/3rdparty/icewind/smb/src/AnonymousAuth.php @@ -21,7 +21,6 @@ namespace Icewind\SMB; - class AnonymousAuth implements IAuth { public function getUsername() { return null; diff --git a/apps/files_external/3rdparty/icewind/smb/src/BasicAuth.php b/apps/files_external/3rdparty/icewind/smb/src/BasicAuth.php index 0032dc5303..9d7f9b5d30 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/BasicAuth.php +++ b/apps/files_external/3rdparty/icewind/smb/src/BasicAuth.php @@ -21,7 +21,6 @@ namespace Icewind\SMB; - class BasicAuth implements IAuth { /** @var string */ private $username; @@ -62,5 +61,4 @@ class BasicAuth implements IAuth { public function setExtraSmbClientOptions($smbClientState) { // noop } - } diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/AccessDeniedException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/AccessDeniedException.php index 4b7d22b354..adc42344b4 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/AccessDeniedException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/AccessDeniedException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class AccessDeniedException extends ConnectException {} +class AccessDeniedException extends ConnectException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/AlreadyExistsException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/AlreadyExistsException.php index 4636b9d178..aaa5226f79 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/AlreadyExistsException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/AlreadyExistsException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class AlreadyExistsException extends InvalidRequestException {} +class AlreadyExistsException extends InvalidRequestException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/AuthenticationException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/AuthenticationException.php index ddf5d7e34d..9626d795e3 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/AuthenticationException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/AuthenticationException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class AuthenticationException extends ConnectException{} +class AuthenticationException extends ConnectException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectException.php index 310d441bf5..9aa174ba5b 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class ConnectException extends Exception {} +class ConnectException extends Exception { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionException.php index 21033560fc..d27752e702 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/ConnectionException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class ConnectionException extends ConnectException {} +class ConnectionException extends ConnectException { +} 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 93f2c1b3e2..4954518f98 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php @@ -8,7 +8,7 @@ namespace Icewind\SMB\Exception; class Exception extends \Exception { - static public function unknown($path, $error) { + public static function unknown($path, $error) { $message = 'Unknown error (' . $error . ')'; if ($path) { $message .= ' for ' . $path; @@ -23,7 +23,7 @@ class Exception extends \Exception { * @param string $path * @return Exception */ - static public function fromMap(array $exceptionMap, $error, $path) { + public static function fromMap(array $exceptionMap, $error, $path) { if (isset($exceptionMap[$error])) { $exceptionClass = $exceptionMap[$error]; if (is_numeric($error)) { diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/FileInUseException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/FileInUseException.php index 46460eb693..4408d39e06 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/FileInUseException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/FileInUseException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class FileInUseException extends InvalidRequestException {} +class FileInUseException extends InvalidRequestException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/ForbiddenException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/ForbiddenException.php index 117d6a438e..31c051893e 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/ForbiddenException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/ForbiddenException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class ForbiddenException extends InvalidRequestException {} +class ForbiddenException extends InvalidRequestException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidArgumentException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidArgumentException.php index f12bb3a348..a21d069d47 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidArgumentException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidArgumentException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class InvalidArgumentException extends InvalidRequestException {} +class InvalidArgumentException extends InvalidRequestException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidHostException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidHostException.php index 4b17f1a4de..2358b7f338 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidHostException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidHostException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class InvalidHostException extends ConnectException {} +class InvalidHostException extends ConnectException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidParameterException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidParameterException.php index 163b571183..5ffbf4f381 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidParameterException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidParameterException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class InvalidParameterException extends InvalidRequestException {} +class InvalidParameterException extends InvalidRequestException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidPathException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidPathException.php index 4bba74f269..2b7859de15 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidPathException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidPathException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class InvalidPathException extends InvalidRequestException {} +class InvalidPathException extends InvalidRequestException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTypeException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTypeException.php index 63b79305ad..00da288b8a 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTypeException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/InvalidTypeException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class InvalidTypeException extends InvalidRequestException {} +class InvalidTypeException extends InvalidRequestException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/NoLoginServerException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/NoLoginServerException.php index 43f7f9aeff..8f0c553928 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/NoLoginServerException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/NoLoginServerException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class NoLoginServerException extends ConnectException {} +class NoLoginServerException extends ConnectException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/NotEmptyException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/NotEmptyException.php index 789a76bcb9..0e606d65ca 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/NotEmptyException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/NotEmptyException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class NotEmptyException extends InvalidRequestException {} +class NotEmptyException extends InvalidRequestException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/NotFoundException.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/NotFoundException.php index 9ce97cd535..29ea2d87c9 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Exception/NotFoundException.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/NotFoundException.php @@ -7,4 +7,5 @@ namespace Icewind\SMB\Exception; -class NotFoundException extends InvalidRequestException {} +class NotFoundException extends InvalidRequestException { +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/INotifyHandler.php b/apps/files_external/3rdparty/icewind/smb/src/INotifyHandler.php index 1ee59b26dd..c3ee3ffe8c 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/INotifyHandler.php +++ b/apps/files_external/3rdparty/icewind/smb/src/INotifyHandler.php @@ -8,7 +8,6 @@ namespace Icewind\SMB; - interface INotifyHandler { // https://msdn.microsoft.com/en-us/library/dn392331.aspx const NOTIFY_ADDED = 1; diff --git a/apps/files_external/3rdparty/icewind/smb/src/IOptions.php b/apps/files_external/3rdparty/icewind/smb/src/IOptions.php new file mode 100644 index 0000000000..c46d2c8b3d --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/IOptions.php @@ -0,0 +1,29 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace Icewind\SMB; + +interface IOptions { + /** + * @return int + */ + public function getTimeout(); +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/IServer.php b/apps/files_external/3rdparty/icewind/smb/src/IServer.php index 2c8d5c67de..0b832025aa 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/IServer.php +++ b/apps/files_external/3rdparty/icewind/smb/src/IServer.php @@ -52,13 +52,18 @@ interface IServer { public function getTimeZone(); /** - * @return System + * @return ISystem */ public function getSystem(); /** - * @param System $system + * @return IOptions + */ + public function getOptions(); + + /** + * @param ISystem $system * @return bool */ - public static function available(System $system); + public static function available(ISystem $system); } diff --git a/apps/files_external/3rdparty/icewind/smb/src/IShare.php b/apps/files_external/3rdparty/icewind/smb/src/IShare.php index 8f6d5058b8..92a12b46f2 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/IShare.php +++ b/apps/files_external/3rdparty/icewind/smb/src/IShare.php @@ -52,6 +52,7 @@ interface IShare { /** * Open a writable stream to a remote file + * Note: This method will truncate the file to 0bytes * * @param string $target * @return resource a write only stream to upload a remote file @@ -61,6 +62,18 @@ interface IShare { */ public function write($target); + /** + * Open a writable stream to a remote file and set the cursor to the end of the file + * + * @param string $target + * @return resource a write only stream to upload a remote file + * + * @throws \Icewind\SMB\Exception\NotFoundException + * @throws \Icewind\SMB\Exception\InvalidTypeException + * @throws \Icewind\SMB\Exception\InvalidRequestException + */ + public function append($target); + /** * Rename a remote file * diff --git a/apps/files_external/3rdparty/icewind/smb/src/ISystem.php b/apps/files_external/3rdparty/icewind/smb/src/ISystem.php new file mode 100644 index 0000000000..7740c98d97 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/ISystem.php @@ -0,0 +1,71 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace Icewind\SMB; + +/** + * The `ISystem` interface provides a way to access system dependent information + * such as the availability and location of certain binaries. + */ +interface ISystem { + /** + * Get the path to a file descriptor of the current process + * + * @param int $num the file descriptor id + * @return string + */ + public function getFD($num); + + /** + * Get the full path to the `smbclient` binary of false if the binary is not available + * + * @return string|bool + */ + public function getSmbclientPath(); + + /** + * Get the full path to the `net` binary of false if the binary is not available + * + * @return string|bool + */ + public function getNetPath(); + + /** + * Get the full path to the `stdbuf` binary of false if the binary is not available + * + * @return string|bool + */ + public function getStdBufPath(); + + /** + * Get the full path to the `date` binary of false if the binary is not available + * + * @return string|bool + */ + public function getDatePath(); + + /** + * Whether or not the smbclient php extension is enabled + * + * @return bool + */ + public function libSmbclientAvailable(); +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/ITimeZoneProvider.php b/apps/files_external/3rdparty/icewind/smb/src/ITimeZoneProvider.php new file mode 100644 index 0000000000..56e09ffb39 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/ITimeZoneProvider.php @@ -0,0 +1,32 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace Icewind\SMB; + +interface ITimeZoneProvider { + /** + * Get the timezone of the smb server + * + * @param string $host + * @return string + */ + public function get($host); +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/KerberosAuth.php b/apps/files_external/3rdparty/icewind/smb/src/KerberosAuth.php index 9510a6dc27..0e91202cb7 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/KerberosAuth.php +++ b/apps/files_external/3rdparty/icewind/smb/src/KerberosAuth.php @@ -45,5 +45,4 @@ class KerberosAuth implements IAuth { smbclient_option_set($smbClientState, SMBCLIENT_OPT_USE_KERBEROS, true); smbclient_option_set($smbClientState, SMBCLIENT_OPT_FALLBACK_AFTER_KERBEROS, false); } - } diff --git a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeFileInfo.php b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeFileInfo.php index 3466797e21..904318907f 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeFileInfo.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeFileInfo.php @@ -30,7 +30,10 @@ class NativeFileInfo implements IFileInfo { /** * @var array|null */ - protected $statCache; + protected $statCache = null; + + /** @var callable|null */ + protected $statCallback = null; /** * @var int @@ -41,13 +44,20 @@ class NativeFileInfo implements IFileInfo { * @param NativeShare $share * @param string $path * @param string $name - * @param array $stat + * @param array|callable $stat */ - public function __construct($share, $path, $name, $stat = null) { + public function __construct($share, $path, $name, $stat) { $this->share = $share; $this->path = $path; $this->name = $name; - $this->statCache = $stat; + + if (is_array($stat)) { + $this->statCache = $stat; + } elseif (is_callable($stat)) { + $this->statCallback = $stat; + } else { + throw new \InvalidArgumentException('$stat needs to be an array or callback'); + } } /** @@ -69,7 +79,7 @@ class NativeFileInfo implements IFileInfo { */ protected function stat() { if (is_null($this->statCache)) { - $this->statCache = $this->share->getStat($this->getPath()); + $this->statCache = call_user_func($this->statCallback); } return $this->statCache; } diff --git a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeReadStream.php b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeReadStream.php index 3ef5b21639..fe0af760d3 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeReadStream.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeReadStream.php @@ -25,7 +25,6 @@ class NativeReadStream extends NativeStream { $this->readBuffer = fopen('php://memory', 'r+'); return parent::stream_open($path, $mode, $options, $opened_path); - } /** @@ -39,13 +38,13 @@ class NativeReadStream extends NativeStream { */ public static function wrap($state, $smbStream, $mode, $url) { stream_wrapper_register('nativesmb', NativeReadStream::class); - $context = stream_context_create(array( - 'nativesmb' => array( + $context = stream_context_create([ + 'nativesmb' => [ 'state' => $state, 'handle' => $smbStream, 'url' => $url - ) - )); + ] + ]); $fh = fopen('nativesmb://', $mode, false, $context); stream_wrapper_unregister('nativesmb'); return $fh; diff --git a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeServer.php b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeServer.php index c6274e59b5..aadb05d0fe 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeServer.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeServer.php @@ -9,7 +9,8 @@ namespace Icewind\SMB\Native; use Icewind\SMB\AbstractServer; use Icewind\SMB\IAuth; -use Icewind\SMB\System; +use Icewind\SMB\IOptions; +use Icewind\SMB\ISystem; use Icewind\SMB\TimeZoneProvider; class NativeServer extends AbstractServer { @@ -18,19 +19,13 @@ class NativeServer extends AbstractServer { */ protected $state; - /** - * @param string $host - * @param IAuth $auth - * @param System $system - * @param TimeZoneProvider $timeZoneProvider - */ - public function __construct($host, IAuth $auth, System $system, TimeZoneProvider $timeZoneProvider) { - parent::__construct($host, $auth, $system, $timeZoneProvider); + public function __construct($host, IAuth $auth, ISystem $system, TimeZoneProvider $timeZoneProvider, IOptions $options) { + parent::__construct($host, $auth, $system, $timeZoneProvider, $options); $this->state = new NativeState(); } protected function connect() { - $this->state->init($this->getAuth()); + $this->state->init($this->getAuth(), $this->getOptions()); } /** @@ -40,7 +35,7 @@ class NativeServer extends AbstractServer { */ public function listShares() { $this->connect(); - $shares = array(); + $shares = []; $dh = $this->state->opendir('smb://' . $this->getHost()); while ($share = $this->state->readdir($dh)) { if ($share['type'] === 'file share') { @@ -62,10 +57,10 @@ class NativeServer extends AbstractServer { /** * Check if the smbclient php extension is available * - * @param System $system + * @param ISystem $system * @return bool */ - public static function available(System $system) { - return function_exists('smbclient_state_new'); + public static function available(ISystem $system) { + return $system->libSmbclientAvailable(); } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeShare.php b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeShare.php index 130a5a070f..1a33f4b0d3 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeShare.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeShare.php @@ -53,7 +53,7 @@ class NativeShare extends AbstractShare { } $this->state = new NativeState(); - $this->state->init($this->server->getAuth()); + $this->state->init($this->server->getAuth(), $this->server->getOptions()); return $this->state; } @@ -87,13 +87,16 @@ class NativeShare extends AbstractShare { * @throws \Icewind\SMB\Exception\InvalidTypeException */ public function dir($path) { - $files = array(); + $files = []; $dh = $this->getState()->opendir($this->buildUrl($path)); while ($file = $this->getState()->readdir($dh)) { $name = $file['name']; if ($name !== '.' and $name !== '..') { - $files [] = new NativeFileInfo($this, $path . '/' . $name, $name); + $fullPath = $path . '/' . $name; + $files [] = new NativeFileInfo($this, $fullPath, $name, function () use ($fullPath) { + return $this->getStat($fullPath); + }); } } @@ -106,10 +109,27 @@ class NativeShare extends AbstractShare { * @return \Icewind\SMB\IFileInfo */ public function stat($path) { - return new NativeFileInfo($this, $path, basename($path), $this->getStat($path)); + return new NativeFileInfo($this, $path, self::mb_basename($path), $this->getStat($path)); } - public function getStat($path) { + /** + * Multibyte unicode safe version of basename() + * + * @param string $path + * @link http://php.net/manual/en/function.basename.php#121405 + * @return string + */ + protected static function mb_basename($path) { + if (preg_match('@^.*[\\\\/]([^\\\\/]+)$@s', $path, $matches)) { + return $matches[1]; + } elseif (preg_match('@^([^\\\\/]+)$@s', $path, $matches)) { + return $matches[1]; + } + + return ''; + } + + private function getStat($path) { return $this->getState()->stat($this->buildUrl($path)); } @@ -228,7 +248,7 @@ class NativeShare extends AbstractShare { } /** - * Open a readable stream top a remote file + * Open a readable stream to a remote file * * @param string $source * @return resource a read only stream with the contents of the remote file @@ -243,10 +263,11 @@ class NativeShare extends AbstractShare { } /** - * Open a readable stream top a remote file + * Open a writeable stream to a remote file + * Note: This method will truncate the file to 0bytes first * * @param string $source - * @return resource a read only stream with the contents of the remote file + * @return resource a writeable stream * * @throws \Icewind\SMB\Exception\NotFoundException * @throws \Icewind\SMB\Exception\InvalidTypeException @@ -257,6 +278,21 @@ class NativeShare extends AbstractShare { return NativeWriteStream::wrap($this->getState(), $handle, 'w', $url); } + /** + * Open a writeable stream and set the cursor to the end of the stream + * + * @param string $source + * @return resource a writeable stream + * + * @throws \Icewind\SMB\Exception\NotFoundException + * @throws \Icewind\SMB\Exception\InvalidTypeException + */ + public function append($source) { + $url = $this->buildUrl($source); + $handle = $this->getState()->open($url, "a"); + return NativeWriteStream::wrap($this->getState(), $handle, "a", $url); + } + /** * Get extended attributes for the path * @@ -269,15 +305,14 @@ class NativeShare extends AbstractShare { } /** - * Get extended attributes for the path + * Set extended attributes for the given path * * @param string $path * @param string $attribute attribute to get the info - * @param mixed $value - * @return string the attribute value + * @param string|int $value + * @return mixed the attribute value */ public function setAttribute($path, $attribute, $value) { - if ($attribute === 'system.dos_attr.mode' and is_int($value)) { $value = '0x' . dechex($value); } @@ -286,6 +321,8 @@ class NativeShare extends AbstractShare { } /** + * Set DOS comaptible node mode + * * @param string $path * @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL * @return mixed @@ -295,16 +332,19 @@ class NativeShare extends AbstractShare { } /** + * Start smb notify listener + * Note: This is a blocking call + * * @param string $path * @return INotifyHandler */ public function notify($path) { - // php-smbclient does support notify (https://github.com/eduardok/libsmbclient-php/issues/29) + // php-smbclient does not support notify (https://github.com/eduardok/libsmbclient-php/issues/29) // so we use the smbclient based backend for this if (!Server::available($this->server->getSystem())) { throw new DependencyException('smbclient not found in path for notify command'); } - $share = new Share($this->server, $this->getName()); + $share = new Share($this->server, $this->getName(), $this->server->getSystem()); return $share->notify($path); } diff --git a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeState.php b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeState.php index 179ba95bea..5ab129cbfd 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeState.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeState.php @@ -21,6 +21,7 @@ use Icewind\SMB\Exception\NotFoundException; use Icewind\SMB\Exception\OutOfSpaceException; use Icewind\SMB\Exception\TimedOutException; use Icewind\SMB\IAuth; +use Icewind\SMB\IOptions; /** * Low level wrapper for libsmbclient-php with error handling @@ -76,14 +77,16 @@ class NativeState { /** * @param IAuth $auth + * @param IOptions $options * @return bool */ - public function init(IAuth $auth) { + public function init(IAuth $auth, IOptions $options) { if ($this->connected) { return true; } $this->state = smbclient_state_new(); smbclient_option_set($this->state, SMBCLIENT_OPT_AUTO_ANONYMOUS_LOGIN, false); + smbclient_option_set($this->state, SMBCLIENT_OPT_TIMEOUT, $options->getTimeout() * 1000); $auth->setExtraSmbClientOptions($this->state); $result = @smbclient_state_init($this->state, $auth->getWorkgroup(), $auth->getUsername(), $auth->getPassword()); diff --git a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeStream.php b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeStream.php index 3b3c65de27..dd92edcbf5 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeStream.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeStream.php @@ -48,13 +48,13 @@ class NativeStream implements File { */ public static function wrap($state, $smbStream, $mode, $url) { stream_wrapper_register('nativesmb', NativeStream::class); - $context = stream_context_create(array( - 'nativesmb' => array( + $context = stream_context_create([ + 'nativesmb' => [ 'state' => $state, 'handle' => $smbStream, 'url' => $url - ) - )); + ] + ]); $fh = fopen('nativesmb://', $mode, false, $context); stream_wrapper_unregister('nativesmb'); return $fh; diff --git a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeWriteStream.php b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeWriteStream.php index f5143a09ae..39eca8175a 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Native/NativeWriteStream.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Native/NativeWriteStream.php @@ -25,7 +25,6 @@ class NativeWriteStream extends NativeStream { $this->writeBuffer = fopen('php://memory', 'r+'); return parent::stream_open($path, $mode, $options, $opened_path); - } /** @@ -39,13 +38,13 @@ class NativeWriteStream extends NativeStream { */ public static function wrap($state, $smbStream, $mode, $url) { stream_wrapper_register('nativesmb', NativeWriteStream::class); - $context = stream_context_create(array( - 'nativesmb' => array( + $context = stream_context_create([ + 'nativesmb' => [ 'state' => $state, 'handle' => $smbStream, 'url' => $url - ) - )); + ] + ]); $fh = fopen('nativesmb://', $mode, false, $context); stream_wrapper_unregister('nativesmb'); return $fh; diff --git a/apps/files_external/3rdparty/icewind/smb/src/Options.php b/apps/files_external/3rdparty/icewind/smb/src/Options.php new file mode 100644 index 0000000000..7a0d0149b7 --- /dev/null +++ b/apps/files_external/3rdparty/icewind/smb/src/Options.php @@ -0,0 +1,35 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace Icewind\SMB; + +class Options implements IOptions { + /** @var int */ + private $timeout = 20; + + public function getTimeout() { + return $this->timeout; + } + + public function setTimeout($timeout) { + $this->timeout = $timeout; + } +} diff --git a/apps/files_external/3rdparty/icewind/smb/src/ServerFactory.php b/apps/files_external/3rdparty/icewind/smb/src/ServerFactory.php index b54168a520..807b0b872c 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/ServerFactory.php +++ b/apps/files_external/3rdparty/icewind/smb/src/ServerFactory.php @@ -21,7 +21,6 @@ namespace Icewind\SMB; - use Icewind\SMB\Exception\DependencyException; use Icewind\SMB\Native\NativeServer; use Icewind\SMB\Wrapped\Server; @@ -32,8 +31,41 @@ class ServerFactory { Server::class ]; - /** @var System|null */ - private $system = null; + /** @var System */ + private $system; + + /** @var IOptions */ + private $options; + + /** @var ITimeZoneProvider */ + private $timeZoneProvider; + + /** + * ServerFactory constructor. + * + * @param IOptions|null $options + * @param ISystem|null $system + * @param ITimeZoneProvider|null $timeZoneProvider + */ + public function __construct( + IOptions $options = null, + ISystem $system = null, + ITimeZoneProvider $timeZoneProvider = null + ) { + if (is_null($options)) { + $options = new Options(); + } + if (is_null($system)) { + $system = new System(); + } + if (is_null($timeZoneProvider)) { + $timeZoneProvider = new TimeZoneProvider($system); + } + $this->options = $options; + $this->system = $system; + $this->timeZoneProvider = $timeZoneProvider; + } + /** * @param $host @@ -43,22 +75,11 @@ class ServerFactory { */ public function createServer($host, IAuth $credentials) { foreach (self::BACKENDS as $backend) { - if (call_user_func("$backend::available", $this->getSystem())) { - return new $backend($host, $credentials, $this->getSystem(), new TimeZoneProvider($host, $this->getSystem())); + if (call_user_func("$backend::available", $this->system)) { + return new $backend($host, $credentials, $this->system, $this->timeZoneProvider, $this->options); } } throw new DependencyException('No valid backend available, ensure smbclient is in the path or php-smbclient is installed'); } - - /** - * @return System - */ - private function getSystem() { - if (is_null($this->system)) { - $this->system = new System(); - } - - return $this->system; - } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/System.php b/apps/files_external/3rdparty/icewind/smb/src/System.php index 30592dd262..3428dd87cd 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/System.php +++ b/apps/files_external/3rdparty/icewind/smb/src/System.php @@ -9,14 +9,18 @@ namespace Icewind\SMB; use Icewind\SMB\Exception\Exception; -class System { - private $smbclient; +class System implements ISystem { + /** @var (string|bool)[] */ + private $paths = []; - private $net; - - private $stdbuf; - - public static function getFD($num) { + /** + * Get the path to a file descriptor of the current process + * + * @param int $num the file descriptor id + * @return string + * @throws Exception + */ + public function getFD($num) { $folders = [ '/proc/self/fd', '/dev/fd' @@ -30,26 +34,32 @@ class System { } public function getSmbclientPath() { - if (!$this->smbclient) { - $this->smbclient = trim(`which smbclient`); - } - return $this->smbclient; + return $this->getBinaryPath('smbclient'); } public function getNetPath() { - if (!$this->net) { - $this->net = trim(`which net`); - } - return $this->net; + return $this->getBinaryPath('net'); } - public function hasStdBuf() { - if (!$this->stdbuf) { + public function getStdBufPath() { + return $this->getBinaryPath('stdbuf'); + } + + public function getDatePath() { + return $this->getBinaryPath('date'); + } + + public function libSmbclientAvailable() { + return function_exists('smbclient_state_new'); + } + + protected function getBinaryPath($binary) { + if (!isset($this->paths[$binary])) { $result = null; - $output = array(); - exec('which stdbuf 2>&1', $output, $result); - $this->stdbuf = $result === 0; + $output = []; + exec("which $binary 2>&1", $output, $result); + $this->paths[$binary] = $result === 0 ? trim(implode('', $output)) : false; } - return $this->stdbuf; + return $this->paths[$binary]; } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php b/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php index 8dce76cb77..7ae049c406 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php +++ b/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php @@ -7,48 +7,48 @@ namespace Icewind\SMB; -class TimeZoneProvider { +class TimeZoneProvider implements ITimeZoneProvider { /** - * @var string + * @var string[] */ - private $host; + private $timeZones = []; /** - * @var string - */ - private $timeZone; - - /** - * @var System + * @var ISystem */ private $system; /** - * @param string $host - * @param System $system + * @param ISystem $system */ - public function __construct($host, System $system) { - $this->host = $host; + public function __construct(ISystem $system) { $this->system = $system; } - public function get() { - if (!$this->timeZone) { + public function get($host) { + if (!isset($this->timeZones[$host])) { + $timeZone = null; $net = $this->system->getNetPath(); // for local domain names we can assume same timezone - if ($net && strpos($this->host, '.') !== false) { - $command = sprintf('%s time zone -S %s', + if ($net && $host && strpos($host, '.') !== false) { + $command = sprintf( + '%s time zone -S %s', $net, - escapeshellarg($this->host) + escapeshellarg($host) ); - $this->timeZone = exec($command); + $timeZone = exec($command); } - if ($this->timeZone) { - // fallback to server timezone - $this->timeZone = date_default_timezone_get(); + if (!$timeZone) { + $date = $this->system->getDatePath(); + if ($date) { + $timeZone = exec($date . " +%z"); + } else { + $timeZone = date_default_timezone_get(); + } } + $this->timeZones[$host] = $timeZone; } - return $this->timeZone; + return $this->timeZones[$host]; } } diff --git a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Connection.php b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Connection.php index 7eddb85ac4..de0a1de40e 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Connection.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Connection.php @@ -20,7 +20,7 @@ class Connection extends RawConnection { /** @var Parser */ private $parser; - public function __construct($command, Parser $parser, $env = array()) { + public function __construct($command, Parser $parser, $env = []) { parent::__construct($command, $env); $this->parser = $parser; } @@ -65,7 +65,7 @@ class Connection extends RawConnection { $promptLine = $this->readLine(); //first line is prompt $this->parser->checkConnectionError($promptLine); - $output = array(); + $output = []; $line = $this->readLine(); if ($line === false) { $this->unknownError($promptLine); diff --git a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/NotifyHandler.php b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/NotifyHandler.php index a32ae3cafa..090734381b 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/NotifyHandler.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/NotifyHandler.php @@ -8,7 +8,6 @@ namespace Icewind\SMB\Wrapped; - use Icewind\SMB\Change; use Icewind\SMB\Exception\Exception; use Icewind\SMB\Exception\RevisionMismatchException; diff --git a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Parser.php b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Parser.php index c446ae85b3..9eee686c0b 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Parser.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Parser.php @@ -19,15 +19,19 @@ use Icewind\SMB\Exception\InvalidTypeException; use Icewind\SMB\Exception\NoLoginServerException; use Icewind\SMB\Exception\NotEmptyException; use Icewind\SMB\Exception\NotFoundException; -use Icewind\SMB\TimeZoneProvider; class Parser { const MSG_NOT_FOUND = 'Error opening local file '; /** - * @var \Icewind\SMB\TimeZoneProvider + * @var string */ - protected $timeZoneProvider; + protected $timeZone; + + /** + * @var string + */ + private $host; // todo replace with static once <5.6 support is dropped // see error.h @@ -55,10 +59,10 @@ class Parser { ]; /** - * @param TimeZoneProvider $timeZoneProvider + * @param string $timeZone */ - public function __construct(TimeZoneProvider $timeZoneProvider) { - $this->timeZoneProvider = $timeZoneProvider; + public function __construct($timeZone) { + $this->timeZone = $timeZone; } private function getErrorCode($line) { @@ -135,7 +139,10 @@ class Parser { $name = isset($words[0]) ? $words[0] : ''; $value = isset($words[1]) ? $words[1] : ''; $value = trim($value); - $data[$name] = $value; + + if (!isset($data[$name])) { + $data[$name] = $value; + } } return [ 'mtime' => strtotime($data['write_time']), @@ -149,13 +156,13 @@ class Parser { array_pop($output); $regex = '/^\s*(.*?)\s\s\s\s+(?:([NDHARS]*)\s+)?([0-9]+)\s+(.*)$/'; //2 spaces, filename, optional type, size, date - $content = array(); + $content = []; foreach ($output as $line) { if (preg_match($regex, $line, $matches)) { list(, $name, $mode, $size, $time) = $matches; if ($name !== '.' and $name !== '..') { $mode = $this->parseMode($mode); - $time = strtotime($time . ' ' . $this->timeZoneProvider->get()); + $time = strtotime($time . ' ' . $this->timeZone); $content[] = new FileInfo($basePath . '/' . $name, $name, $size, $time, $mode); } } @@ -164,14 +171,14 @@ class Parser { } public function parseListShares($output) { - $shareNames = array(); + $shareNames = []; foreach ($output as $line) { if (strpos($line, '|')) { list($type, $name, $description) = explode('|', $line); if (strtolower($type) === 'disk') { $shareNames[$name] = $description; } - } else if (strpos($line, 'Disk')) { + } elseif (strpos($line, 'Disk')) { // new output format list($name, $description) = explode('Disk', $line); $shareNames[trim($name)] = trim($description); diff --git a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Server.php b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Server.php index cc0f13f360..b3763a7324 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Server.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Server.php @@ -13,22 +13,22 @@ use Icewind\SMB\Exception\ConnectException; use Icewind\SMB\Exception\ConnectionException; use Icewind\SMB\Exception\InvalidHostException; use Icewind\SMB\IShare; -use Icewind\SMB\System; +use Icewind\SMB\ISystem; class Server extends AbstractServer { /** * Check if the smbclient php extension is available * - * @param System $system + * @param ISystem $system * @return bool */ - public static function available(System $system) { + public static function available(ISystem $system) { return $system->getSmbclientPath(); } private function getAuthFileArgument() { if ($this->getAuth()->getUsername()) { - return '--authentication-file=' . System::getFD(3); + return '--authentication-file=' . $this->system->getFD(3); } else { return ''; } @@ -42,7 +42,8 @@ class Server extends AbstractServer { * @throws ConnectException */ public function listShares() { - $command = sprintf('%s %s %s -L %s', + $command = sprintf( + '%s %s %s -L %s', $this->system->getSmbclientPath(), $this->getAuthFileArgument(), $this->getAuth()->getExtraCommandLineArguments(), @@ -73,7 +74,7 @@ class Server extends AbstractServer { $shareNames = $parser->parseListShares($output); - $shares = array(); + $shares = []; foreach ($shareNames as $name => $description) { $shares[] = $this->getShare($name); } diff --git a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Share.php b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Share.php index 4ef0be583d..5a79c49fec 100644 --- a/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Share.php +++ b/apps/files_external/3rdparty/icewind/smb/src/Wrapped/Share.php @@ -13,12 +13,14 @@ use Icewind\SMB\Exception\DependencyException; use Icewind\SMB\Exception\FileInUseException; use Icewind\SMB\Exception\InvalidTypeException; use Icewind\SMB\Exception\NotFoundException; +use Icewind\SMB\Exception\InvalidRequestException; use Icewind\SMB\IFileInfo; use Icewind\SMB\INotifyHandler; use Icewind\SMB\IServer; -use Icewind\SMB\System; -use Icewind\SMB\TimeZoneProvider; +use Icewind\SMB\ISystem; use Icewind\Streams\CallbackWrapper; +use Icewind\SMB\Native\NativeShare; +use Icewind\SMB\Native\NativeServer; class Share extends AbstractShare { /** @@ -42,7 +44,7 @@ class Share extends AbstractShare { protected $parser; /** - * @var System + * @var ISystem */ private $system; @@ -56,28 +58,30 @@ class Share extends AbstractShare { /** * @param IServer $server * @param string $name - * @param System $system + * @param ISystem $system */ - public function __construct(IServer $server, $name, System $system = null) { + public function __construct(IServer $server, $name, ISystem $system) { parent::__construct(); $this->server = $server; $this->name = $name; - $this->system = (!is_null($system)) ? $system : new System(); - $this->parser = new Parser(new TimeZoneProvider($this->server->getHost(), $this->system)); + $this->system = $system; + $this->parser = new Parser($server->getTimeZone()); } private function getAuthFileArgument() { if ($this->server->getAuth()->getUsername()) { - return '--authentication-file=' . System::getFD(3); + return '--authentication-file=' . $this->system->getFD(3); } else { return ''; } } protected function getConnection() { - $command = sprintf('%s%s %s %s %s', - $this->system->hasStdBuf() ? 'stdbuf -o0 ' : '', + $command = sprintf( + '%s%s -t %s %s %s %s', + $this->system->getStdBufPath() ? $this->system->getStdBufPath() . ' -o0 ' : '', $this->system->getSmbclientPath(), + $this->server->getOptions()->getTimeout(), $this->getAuthFileArgument(), $this->server->getAuth()->getExtraCommandLineArguments(), escapeshellarg('//' . $this->server->getHost() . '/' . $this->name) @@ -159,13 +163,14 @@ class Share extends AbstractShare { if ($path !== "" && $path !== "/") { $parent = dirname($path); $dir = $this->dir($parent); - $file = array_values(array_filter($dir, function(IFileInfo $info) use ($path) { + $file = array_values(array_filter($dir, function (IFileInfo $info) use ($path) { return $info->getPath() === $path; })); if ($file) { return $file[0]; } } + $escapedPath = $this->escapePath($path); $output = $this->execute('allinfo ' . $escapedPath); // Windows and non Windows Fileserver may respond different @@ -307,7 +312,7 @@ class Share extends AbstractShare { // since we can't re-use the same file descriptor over multiple calls $connection = $this->getConnection(); - $connection->write('get ' . $source . ' ' . System::getFD(5)); + $connection->write('get ' . $source . ' ' . $this->system->getFD(5)); $connection->write('exit'); $fh = $connection->getFileOutputStream(); stream_context_set_option($fh, 'file', 'connection', $connection); @@ -330,7 +335,7 @@ class Share extends AbstractShare { $connection = $this->getConnection(); $fh = $connection->getFileInputStream(); - $connection->write('put ' . System::getFD(4) . ' ' . $target); + $connection->write('put ' . $this->system->getFD(4) . ' ' . $target); $connection->write('exit'); // use a close callback to ensure the upload is finished before continuing @@ -340,6 +345,18 @@ class Share extends AbstractShare { }); } + /** + * Append to stream + * Note: smbclient does not support this (Use php-libsmbclient) + * + * @param string $target + * + * @throws \Icewind\SMB\Exception\DependencyException + */ + public function append($target) { + throw new DependencyException('php-libsmbclient is required for append'); + } + /** * @param string $path * @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL @@ -376,7 +393,7 @@ class Share extends AbstractShare { * @throws DependencyException */ public function notify($path) { - if (!$this->system->hasStdBuf()) { //stdbuf is required to disable smbclient's output buffering + if (!$this->system->getStdBufPath()) { //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