Merge pull request #14064 from nextcloud/smb-3.1.0
update icewind/smb to 3.1.0
This commit is contained in:
commit
c5dc9b57ae
54 changed files with 547 additions and 198 deletions
1
apps/files_external/3rdparty/.gitignore
vendored
1
apps/files_external/3rdparty/.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
example.php
|
||||
.editorconfig
|
||||
icewind/smb/tests
|
||||
icewind/smb/install_libsmbclient.sh
|
||||
icewind/smb/Makefile
|
||||
|
|
2
apps/files_external/3rdparty/composer.json
vendored
2
apps/files_external/3rdparty/composer.json
vendored
|
@ -9,6 +9,6 @@
|
|||
},
|
||||
"require": {
|
||||
"icewind/streams": "0.6.1",
|
||||
"icewind/smb": "3.0.0"
|
||||
"icewind/smb": "3.1.0"
|
||||
}
|
||||
}
|
||||
|
|
13
apps/files_external/3rdparty/composer.lock
generated
vendored
13
apps/files_external/3rdparty/composer.lock
generated
vendored
|
@ -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",
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
.idea
|
||||
vendor
|
||||
composer.lock
|
||||
.php_cs.cache
|
||||
|
||||
|
|
15
apps/files_external/3rdparty/icewind/smb/.php_cs.dist
vendored
Normal file
15
apps/files_external/3rdparty/icewind/smb/.php_cs.dist
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->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)
|
||||
;
|
|
@ -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.
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
namespace Icewind\SMB;
|
||||
|
||||
|
||||
class AnonymousAuth implements IAuth {
|
||||
public function getUsername() {
|
||||
return null;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class AccessDeniedException extends ConnectException {}
|
||||
class AccessDeniedException extends ConnectException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class AlreadyExistsException extends InvalidRequestException {}
|
||||
class AlreadyExistsException extends InvalidRequestException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class AuthenticationException extends ConnectException{}
|
||||
class AuthenticationException extends ConnectException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class ConnectException extends Exception {}
|
||||
class ConnectException extends Exception {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class ConnectionException extends ConnectException {}
|
||||
class ConnectionException extends ConnectException {
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class FileInUseException extends InvalidRequestException {}
|
||||
class FileInUseException extends InvalidRequestException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class ForbiddenException extends InvalidRequestException {}
|
||||
class ForbiddenException extends InvalidRequestException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class InvalidArgumentException extends InvalidRequestException {}
|
||||
class InvalidArgumentException extends InvalidRequestException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class InvalidHostException extends ConnectException {}
|
||||
class InvalidHostException extends ConnectException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class InvalidParameterException extends InvalidRequestException {}
|
||||
class InvalidParameterException extends InvalidRequestException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class InvalidPathException extends InvalidRequestException {}
|
||||
class InvalidPathException extends InvalidRequestException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class InvalidTypeException extends InvalidRequestException {}
|
||||
class InvalidTypeException extends InvalidRequestException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class NoLoginServerException extends ConnectException {}
|
||||
class NoLoginServerException extends ConnectException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class NotEmptyException extends InvalidRequestException {}
|
||||
class NotEmptyException extends InvalidRequestException {
|
||||
}
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
|
||||
namespace Icewind\SMB\Exception;
|
||||
|
||||
class NotFoundException extends InvalidRequestException {}
|
||||
class NotFoundException extends InvalidRequestException {
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
namespace Icewind\SMB;
|
||||
|
||||
|
||||
interface INotifyHandler {
|
||||
// https://msdn.microsoft.com/en-us/library/dn392331.aspx
|
||||
const NOTIFY_ADDED = 1;
|
||||
|
|
29
apps/files_external/3rdparty/icewind/smb/src/IOptions.php
vendored
Normal file
29
apps/files_external/3rdparty/icewind/smb/src/IOptions.php
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Icewind\SMB;
|
||||
|
||||
interface IOptions {
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTimeout();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
71
apps/files_external/3rdparty/icewind/smb/src/ISystem.php
vendored
Normal file
71
apps/files_external/3rdparty/icewind/smb/src/ISystem.php
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
32
apps/files_external/3rdparty/icewind/smb/src/ITimeZoneProvider.php
vendored
Normal file
32
apps/files_external/3rdparty/icewind/smb/src/ITimeZoneProvider.php
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Icewind\SMB;
|
||||
|
||||
interface ITimeZoneProvider {
|
||||
/**
|
||||
* Get the timezone of the smb server
|
||||
*
|
||||
* @param string $host
|
||||
* @return string
|
||||
*/
|
||||
public function get($host);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
35
apps/files_external/3rdparty/icewind/smb/src/Options.php
vendored
Normal file
35
apps/files_external/3rdparty/icewind/smb/src/Options.php
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
namespace Icewind\SMB\Wrapped;
|
||||
|
||||
|
||||
use Icewind\SMB\Change;
|
||||
use Icewind\SMB\Exception\Exception;
|
||||
use Icewind\SMB\Exception\RevisionMismatchException;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue