summaryrefslogtreecommitdiffstats
path: root/apps/files_external/3rdparty/icewind
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2016-12-14 16:22:33 +0100
committerRoeland Jago Douma <roeland@famdouma.nl>2017-01-05 09:16:03 +0100
commit84296877888ff901c1bc5a9264d44ffb915e7c56 (patch)
treece62009cd10f98987606921ec3945160c0de1634 /apps/files_external/3rdparty/icewind
parent6a0f0403d01dc6a889157b446edef73f9af58540 (diff)
downloadnextcloud-server-84296877888ff901c1bc5a9264d44ffb915e7c56.tar.gz
nextcloud-server-84296877888ff901c1bc5a9264d44ffb915e7c56.zip
Update icewind/smb to 2.0.0
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'apps/files_external/3rdparty/icewind')
-rw-r--r--apps/files_external/3rdparty/icewind/smb/README.md18
-rw-r--r--apps/files_external/3rdparty/icewind/smb/composer.json3
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/Connection.php40
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php30
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/IShare.php16
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php4
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/NativeShare.php26
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/NativeState.php70
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/Parser.php141
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/RawConnection.php2
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/Server.php29
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/Share.php86
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/System.php12
-rw-r--r--apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php2
14 files changed, 239 insertions, 240 deletions
diff --git a/apps/files_external/3rdparty/icewind/smb/README.md b/apps/files_external/3rdparty/icewind/smb/README.md
index 32f3c650f87..c8f31193c83 100644
--- a/apps/files_external/3rdparty/icewind/smb/README.md
+++ b/apps/files_external/3rdparty/icewind/smb/README.md
@@ -1,7 +1,7 @@
SMB
===
-[![Coverage Status](https://img.shields.io/coveralls/icewind1991/SMB.svg)](https://coveralls.io/r/icewind1991/SMB?branch=master)
+[![Code Coverage](https://scrutinizer-ci.com/g/icewind1991/SMB/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/icewind1991/SMB/?branch=master)
[![Build Status](https://travis-ci.org/icewind1991/SMB.svg?branch=master)](https://travis-ci.org/icewind1991/SMB)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/icewind1991/SMB/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/icewind1991/SMB/?branch=master)
@@ -134,3 +134,19 @@ if (Server::NativeAvailable()) {
$share = $server->getShare('test');
$share->put($fileToUpload, 'example.txt');
```
+
+### Using notify
+
+```php
+<?php
+use Icewind\SMB\Server;
+
+require('vendor/autoload.php');
+
+$server = new Server('localhost', 'test', 'test');
+$share = $server->getShare('test');
+
+$share->notify('')->listen(function (\Icewind\SMB\Change $change) {
+ echo $change->getCode() . ': ' . $change->getPath() . "\n";
+});
+```
diff --git a/apps/files_external/3rdparty/icewind/smb/composer.json b/apps/files_external/3rdparty/icewind/smb/composer.json
index 4ac8b27e725..8374f564bf1 100644
--- a/apps/files_external/3rdparty/icewind/smb/composer.json
+++ b/apps/files_external/3rdparty/icewind/smb/composer.json
@@ -9,11 +9,10 @@
}
],
"require" : {
- "php": ">=5.3",
+ "php": ">=5.4",
"icewind/streams": ">=0.2.0"
},
"require-dev": {
- "satooshi/php-coveralls" : "v1.0.0",
"phpunit/phpunit": "^4.8"
},
"autoload" : {
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Connection.php b/apps/files_external/3rdparty/icewind/smb/src/Connection.php
index d24cdc1f6d0..c1ebb861711 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/Connection.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/Connection.php
@@ -17,6 +17,14 @@ class Connection extends RawConnection {
const DELIMITER = 'smb:';
const DELIMITER_LENGTH = 4;
+ /** @var Parser */
+ private $parser;
+
+ public function __construct($command, Parser $parser, $env = array()) {
+ parent::__construct($command, $env);
+ $this->parser = $parser;
+ }
+
/**
* send input to smbclient
*
@@ -30,7 +38,7 @@ class Connection extends RawConnection {
* get all unprocessed output from smbclient until the next prompt
*
* @param callable $callback (optional) callback to call for every line read
- * @return string
+ * @return string[]
* @throws AuthenticationException
* @throws ConnectException
* @throws ConnectionException
@@ -42,7 +50,7 @@ class Connection extends RawConnection {
throw new ConnectionException('Connection not valid');
}
$promptLine = $this->readLine(); //first line is prompt
- $this->checkConnectionError($promptLine);
+ $this->parser->checkConnectionError($promptLine);
$output = array();
$line = $this->readLine();
@@ -54,6 +62,7 @@ class Connection extends RawConnection {
$result = $callback($line);
if ($result === false) { // allow the callback to close the connection for infinite running commands
$this->close(true);
+ break;
}
} else {
$output[] .= $line;
@@ -90,33 +99,6 @@ class Connection extends RawConnection {
}
}
- /**
- * check if the first line holds a connection failure
- *
- * @param $line
- * @throws AuthenticationException
- * @throws InvalidHostException
- * @throws NoLoginServerException
- */
- private function checkConnectionError($line) {
- $line = rtrim($line, ')');
- if (substr($line, -23) === ErrorCodes::LogonFailure) {
- throw new AuthenticationException('Invalid login');
- }
- if (substr($line, -26) === ErrorCodes::BadHostName) {
- throw new InvalidHostException('Invalid hostname');
- }
- if (substr($line, -22) === ErrorCodes::Unsuccessful) {
- throw new InvalidHostException('Connection unsuccessful');
- }
- if (substr($line, -28) === ErrorCodes::ConnectionRefused) {
- throw new InvalidHostException('Connection refused');
- }
- if (substr($line, -26) === ErrorCodes::NoLogonServers) {
- throw new NoLoginServerException('No login server');
- }
- }
-
public function close($terminate = true) {
if (is_resource($this->getInputStream())) {
$this->write('close' . PHP_EOL);
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php b/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php
index 3307ad57a24..7ac528198a9 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/Exception/Exception.php
@@ -7,4 +7,32 @@
namespace Icewind\SMB\Exception;
-class Exception extends \Exception {}
+class Exception extends \Exception {
+ static public function unknown($path, $error) {
+ $message = 'Unknown error (' . $error . ')';
+ if ($path) {
+ $message .= ' for ' . $path;
+ }
+
+ return new Exception($message, $error);
+ }
+
+ /**
+ * @param array $exceptionMap
+ * @param mixed $error
+ * @param string $path
+ * @return Exception
+ */
+ static public function fromMap(array $exceptionMap, $error, $path) {
+ if (isset($exceptionMap[$error])) {
+ $exceptionClass = $exceptionMap[$error];
+ if (is_numeric($error)) {
+ return new $exceptionClass($path, $error);
+ } else {
+ return new $exceptionClass($path);
+ }
+ } else {
+ return Exception::unknown($path, $error);
+ }
+ }
+}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/IShare.php b/apps/files_external/3rdparty/icewind/smb/src/IShare.php
index 40423151332..8f6d5058b81 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/IShare.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/IShare.php
@@ -8,17 +8,6 @@
namespace Icewind\SMB;
interface IShare {
- // https://msdn.microsoft.com/en-us/library/dn392331.aspx
- const NOTIFY_ADDED = 1;
- const NOTIFY_REMOVED = 2;
- const NOTIFY_MODIFIED = 3;
- const NOTIFY_RENAMED_OLD = 4;
- const NOTIFY_RENAMED_NEW = 5;
- const NOTIFY_ADDED_STREAM = 6;
- const NOTIFY_REMOVED_STREAM = 7;
- const NOTIFY_MODIFIED_STREAM = 8;
- const NOTIFY_REMOVED_BY_DELETE = 9;
-
/**
* Get the name of the share
*
@@ -145,8 +134,7 @@ interface IShare {
/**
* @param string $path
- * @param callable $callback callable which will be called for each received change
- * @return mixed
+ * @return INotifyHandler
*/
- public function notify($path, callable $callback);
+ public function notify($path);
}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php b/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php
index 6ef5cf0c5b9..6cb070196a6 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/NativeFileInfo.php
@@ -26,7 +26,7 @@ class NativeFileInfo implements IFileInfo {
protected $share;
/**
- * @var array | null
+ * @var array|null
*/
protected $statCache;
@@ -66,7 +66,7 @@ class NativeFileInfo implements IFileInfo {
* @return array
*/
protected function stat() {
- if (!$this->statCache) {
+ if (is_null($this->statCache)) {
$this->statCache = $this->share->getStat($this->getPath());
}
return $this->statCache;
diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php
index 51e16d1841f..7efa34df370 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/NativeShare.php
@@ -60,6 +60,7 @@ class NativeShare extends AbstractShare {
}
private function buildUrl($path) {
+ $this->connect();
$this->verifyPath($path);
$url = sprintf('smb://%s/%s', $this->server->getHost(), $this->name);
if ($path) {
@@ -80,7 +81,6 @@ class NativeShare extends AbstractShare {
* @throws \Icewind\SMB\Exception\InvalidTypeException
*/
public function dir($path) {
- $this->connect();
$files = array();
$dh = $this->state->opendir($this->buildUrl($path));
@@ -97,14 +97,13 @@ class NativeShare extends AbstractShare {
/**
* @param string $path
- * @return \Icewind\SMB\IFileInfo[]
+ * @return \Icewind\SMB\IFileInfo
*/
public function stat($path) {
return new NativeFileInfo($this, $path, basename($path), $this->getStat($path));
}
public function getStat($path) {
- $this->connect();
return $this->state->stat($this->buildUrl($path));
}
@@ -118,7 +117,6 @@ class NativeShare extends AbstractShare {
* @throws \Icewind\SMB\Exception\AlreadyExistsException
*/
public function mkdir($path) {
- $this->connect();
return $this->state->mkdir($this->buildUrl($path));
}
@@ -132,7 +130,6 @@ class NativeShare extends AbstractShare {
* @throws \Icewind\SMB\Exception\InvalidTypeException
*/
public function rmdir($path) {
- $this->connect();
return $this->state->rmdir($this->buildUrl($path));
}
@@ -146,7 +143,6 @@ class NativeShare extends AbstractShare {
* @throws \Icewind\SMB\Exception\InvalidTypeException
*/
public function del($path) {
- $this->connect();
return $this->state->unlink($this->buildUrl($path));
}
@@ -161,7 +157,6 @@ class NativeShare extends AbstractShare {
* @throws \Icewind\SMB\Exception\AlreadyExistsException
*/
public function rename($from, $to) {
- $this->connect();
return $this->state->rename($this->buildUrl($from), $this->buildUrl($to));
}
@@ -176,7 +171,6 @@ class NativeShare extends AbstractShare {
* @throws \Icewind\SMB\Exception\InvalidTypeException
*/
public function put($source, $target) {
- $this->connect();
$sourceHandle = fopen($source, 'rb');
$targetHandle = $this->state->create($this->buildUrl($target));
@@ -214,7 +208,6 @@ class NativeShare extends AbstractShare {
throw new InvalidResourceException('Failed opening local file "' . $target . '" for writing: ' . $reason);
}
- $this->connect();
$sourceHandle = $this->state->open($this->buildUrl($source), 'r');
if (!$sourceHandle) {
fclose($targetHandle);
@@ -238,7 +231,6 @@ class NativeShare extends AbstractShare {
* @throws \Icewind\SMB\Exception\InvalidTypeException
*/
public function read($source) {
- $this->connect();
$url = $this->buildUrl($source);
$handle = $this->state->open($url, 'r');
return NativeStream::wrap($this->state, $handle, 'r', $url);
@@ -254,7 +246,6 @@ class NativeShare extends AbstractShare {
* @throws \Icewind\SMB\Exception\InvalidTypeException
*/
public function write($source) {
- $this->connect();
$url = $this->buildUrl($source);
$handle = $this->state->create($url);
return NativeStream::wrap($this->state, $handle, 'w', $url);
@@ -268,10 +259,7 @@ class NativeShare extends AbstractShare {
* @return string the attribute value
*/
public function getAttribute($path, $attribute) {
- $this->connect();
-
- $result = $this->state->getxattr($this->buildUrl($path), $attribute);
- return $result;
+ return $this->state->getxattr($this->buildUrl($path), $attribute);
}
/**
@@ -283,7 +271,6 @@ class NativeShare extends AbstractShare {
* @return string the attribute value
*/
public function setAttribute($path, $attribute, $value) {
- $this->connect();
if ($attribute === 'system.dos_attr.mode' and is_int($value)) {
$value = '0x' . dechex($value);
@@ -303,14 +290,13 @@ class NativeShare extends AbstractShare {
/**
* @param string $path
- * @param callable $callback callable which will be called for each received change
- * @return mixed
+ * @return INotifyHandler
*/
- public function notify($path, callable $callback) {
+ public function notify($path) {
// php-smbclient does support notify (https://github.com/eduardok/libsmbclient-php/issues/29)
// so we use the smbclient based backend for this
$share = new Share($this->server, $this->getName());
- $share->notify($path, $callback);
+ return $share->notify($path);
}
public function __destruct() {
diff --git a/apps/files_external/3rdparty/icewind/smb/src/NativeState.php b/apps/files_external/3rdparty/icewind/smb/src/NativeState.php
index e3e344d9e01..7ddce831853 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/NativeState.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/NativeState.php
@@ -7,16 +7,7 @@
namespace Icewind\SMB;
-use Icewind\SMB\Exception\AlreadyExistsException;
-use Icewind\SMB\Exception\ConnectionRefusedException;
use Icewind\SMB\Exception\Exception;
-use Icewind\SMB\Exception\ForbiddenException;
-use Icewind\SMB\Exception\HostDownException;
-use Icewind\SMB\Exception\InvalidTypeException;
-use Icewind\SMB\Exception\NoRouteToHostException;
-use Icewind\SMB\Exception\NotEmptyException;
-use Icewind\SMB\Exception\NotFoundException;
-use Icewind\SMB\Exception\TimedOutException;
/**
* Low level wrapper for libsmbclient-php for error handling
@@ -31,44 +22,39 @@ class NativeState {
protected $connected = false;
+ // todo replace with static once <5.6 support is dropped
+ // see error.h
+ private static $exceptionMap = [
+ 1 => '\Icewind\SMB\Exception\ForbiddenException',
+ 2 => '\Icewind\SMB\Exception\NotFoundException',
+ 13 => '\Icewind\SMB\Exception\ForbiddenException',
+ 17 => '\Icewind\SMB\Exception\AlreadyExistsException',
+ 20 => '\Icewind\SMB\Exception\InvalidTypeException',
+ 21 => '\Icewind\SMB\Exception\InvalidTypeException',
+ 39 => '\Icewind\SMB\Exception\NotEmptyException',
+ 110 => '\Icewind\SMB\Exception\TimedOutException',
+ 111 => '\Icewind\SMB\Exception\ConnectionRefusedException',
+ 112 => '\Icewind\SMB\Exception\HostDownException',
+ 113 => '\Icewind\SMB\Exception\NoRouteToHostException'
+ ];
+
protected function handleError($path) {
$error = smbclient_state_errno($this->state);
- switch ($error) {
- // see error.h
- case 0;
- return;
- case 1:
- case 13:
- throw new ForbiddenException($path, $error);
- case 2:
- throw new NotFoundException($path, $error);
- case 17:
- throw new AlreadyExistsException($path, $error);
- case 20:
- throw new InvalidTypeException($path, $error);
- case 21:
- throw new InvalidTypeException($path, $error);
- case 39:
- throw new NotEmptyException($path, $error);
- case 110:
- throw new TimedOutException($path, $error);
- case 111:
- throw new ConnectionRefusedException($path, $error);
- case 112:
- throw new HostDownException($path, $error);
- case 113:
- throw new NoRouteToHostException($path, $error);
- default:
- $message = 'Unknown error (' . $error . ')';
- if ($path) {
- $message .= ' for ' . $path;
- }
- throw new Exception($message, $error);
+ if ($error === 0) {
+ return;
}
+ throw Exception::fromMap(self::$exceptionMap, $error, $path);
}
- protected function testResult($result, $path) {
+ protected function testResult($result, $uri) {
if ($result === false or $result === null) {
+ // smb://host/share/path
+ if (is_string($uri)) {
+ list(, , , , $path) = explode('/', $uri, 5);
+ $path = '/' . $path;
+ } else {
+ $path = null;
+ }
$this->handleError($path);
}
}
@@ -246,7 +232,7 @@ class NativeState {
* @param resource $file
* @param int $offset
* @param int $whence SEEK_SET | SEEK_CUR | SEEK_END
- * @return int | bool new file offset as measured from the start of the file on success, false on failure.
+ * @return int|bool new file offset as measured from the start of the file on success, false on failure.
*/
public function lseek($file, $offset, $whence = SEEK_SET) {
$result = @smbclient_lseek($this->state, $file, $offset, $whence);
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Parser.php b/apps/files_external/3rdparty/icewind/smb/src/Parser.php
index fc1d7f283a8..5cc5acbdf56 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/Parser.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/Parser.php
@@ -9,19 +9,38 @@ namespace Icewind\SMB;
use Icewind\SMB\Exception\AccessDeniedException;
use Icewind\SMB\Exception\AlreadyExistsException;
+use Icewind\SMB\Exception\AuthenticationException;
use Icewind\SMB\Exception\Exception;
use Icewind\SMB\Exception\FileInUseException;
+use Icewind\SMB\Exception\InvalidHostException;
use Icewind\SMB\Exception\InvalidResourceException;
use Icewind\SMB\Exception\InvalidTypeException;
+use Icewind\SMB\Exception\NoLoginServerException;
use Icewind\SMB\Exception\NotEmptyException;
use Icewind\SMB\Exception\NotFoundException;
class Parser {
+ const MSG_NOT_FOUND = 'Error opening local file ';
+
/**
* @var \Icewind\SMB\TimeZoneProvider
*/
protected $timeZoneProvider;
+ // todo replace with static once <5.6 support is dropped
+ // see error.h
+ private static $exceptionMap = [
+ ErrorCodes::PathNotFound => '\Icewind\SMB\Exception\NotFoundException',
+ ErrorCodes::ObjectNotFound => '\Icewind\SMB\Exception\NotFoundException',
+ ErrorCodes::NoSuchFile => '\Icewind\SMB\Exception\NotFoundException',
+ ErrorCodes::NameCollision => '\Icewind\SMB\Exception\AlreadyExistsException',
+ ErrorCodes::AccessDenied => '\Icewind\SMB\Exception\AccessDeniedException',
+ ErrorCodes::DirectoryNotEmpty => '\Icewind\SMB\Exception\NotEmptyException',
+ ErrorCodes::FileIsADirectory => '\Icewind\SMB\Exception\InvalidTypeException',
+ ErrorCodes::NotADirectory => '\Icewind\SMB\Exception\InvalidTypeException',
+ ErrorCodes::SharingViolation => '\Icewind\SMB\Exception\FileInUseException'
+ ];
+
/**
* @param \Icewind\SMB\TimeZoneProvider $timeZoneProvider
*/
@@ -29,50 +48,54 @@ class Parser {
$this->timeZoneProvider = $timeZoneProvider;
}
- public function checkForError($output, $path) {
- if (count($output) === 0) {
- return true;
- } else {
- if (strpos($output[0], 'does not exist')) {
- throw new NotFoundException($path);
- }
- $parts = explode(' ', $output[0]);
- $error = false;
- foreach ($parts as $part) {
- if (substr($part, 0, 9) === 'NT_STATUS') {
- $error = $part;
- }
+ private function getErrorCode($line) {
+ $parts = explode(' ', $line);
+ foreach ($parts as $part) {
+ if (substr($part, 0, 9) === 'NT_STATUS') {
+ return $part;
}
+ }
+ return false;
+ }
- $notFoundMsg = 'Error opening local file ';
- if (substr($output[0], 0, strlen($notFoundMsg)) === $notFoundMsg) {
- $localPath = substr($output[0], strlen($notFoundMsg));
- throw new InvalidResourceException('Failed opening local file "' . $localPath . '" for writing');
- }
+ public function checkForError($output, $path) {
+ if (strpos($output[0], 'does not exist')) {
+ throw new NotFoundException($path);
+ }
+ $error = $this->getErrorCode($output[0]);
- switch ($error) {
- case ErrorCodes::PathNotFound:
- case ErrorCodes::ObjectNotFound:
- case ErrorCodes::NoSuchFile:
- throw new NotFoundException($path);
- case ErrorCodes::NameCollision:
- throw new AlreadyExistsException($path);
- case ErrorCodes::AccessDenied:
- throw new AccessDeniedException($path);
- case ErrorCodes::DirectoryNotEmpty:
- throw new NotEmptyException($path);
- case ErrorCodes::FileIsADirectory:
- case ErrorCodes::NotADirectory:
- throw new InvalidTypeException($path);
- case ErrorCodes::SharingViolation:
- throw new FileInUseException($path);
- default:
- $message = 'Unknown error (' . $error . ')';
- if ($path) {
- $message .= ' for ' . $path;
- }
- throw new Exception($message);
- }
+ if (substr($output[0], 0, strlen(self::MSG_NOT_FOUND)) === self::MSG_NOT_FOUND) {
+ $localPath = substr($output[0], strlen(self::MSG_NOT_FOUND));
+ throw new InvalidResourceException('Failed opening local file "' . $localPath . '" for writing');
+ }
+
+ throw Exception::fromMap(self::$exceptionMap, $error, $path);
+ }
+
+ /**
+ * check if the first line holds a connection failure
+ *
+ * @param $line
+ * @throws AuthenticationException
+ * @throws InvalidHostException
+ * @throws NoLoginServerException
+ */
+ public function checkConnectionError($line) {
+ $line = rtrim($line, ')');
+ if (substr($line, -23) === ErrorCodes::LogonFailure) {
+ throw new AuthenticationException('Invalid login');
+ }
+ if (substr($line, -26) === ErrorCodes::BadHostName) {
+ throw new InvalidHostException('Invalid hostname');
+ }
+ if (substr($line, -22) === ErrorCodes::Unsuccessful) {
+ throw new InvalidHostException('Connection unsuccessful');
+ }
+ if (substr($line, -28) === ErrorCodes::ConnectionRefused) {
+ throw new InvalidHostException('Connection refused');
+ }
+ if (substr($line, -26) === ErrorCodes::NoLogonServers) {
+ throw new NoLoginServerException('No login server');
}
}
@@ -95,9 +118,7 @@ class Parser {
}
public function parseStat($output) {
- $mtime = 0;
- $mode = 0;
- $size = 0;
+ $data = [];
foreach ($output as $line) {
// A line = explode statement may not fill all array elements
// properly. May happen when accessing non Windows Fileservers
@@ -105,20 +126,13 @@ class Parser {
$name = isset($words[0]) ? $words[0] : '';
$value = isset($words[1]) ? $words[1] : '';
$value = trim($value);
- if ($name === 'write_time') {
- $mtime = strtotime($value);
- } else if ($name === 'attributes') {
- $mode = hexdec(substr($value, 1, -1));
- } else if ($name === 'stream') {
- list(, $size,) = explode(' ', $value);
- $size = intval($size);
- }
+ $data[$name] = $value;
}
- return array(
- 'mtime' => $mtime,
- 'mode' => $mode,
- 'size' => $size
- );
+ return [
+ 'mtime' => strtotime($data['write_time']),
+ 'mode' => hexdec(substr($data['attributes'], strpos($data['attributes'], '('), -1)),
+ 'size' => isset($data['stream']) ? intval(explode(' ', $data['stream'])[1]) : 0
+ ];
}
public function parseDir($output, $basePath) {
@@ -139,4 +153,17 @@ class Parser {
}
return $content;
}
+
+ public function parseListShares($output) {
+ $shareNames = array();
+ foreach ($output as $line) {
+ if (strpos($line, '|')) {
+ list($type, $name, $description) = explode('|', $line);
+ if (strtolower($type) === 'disk') {
+ $shareNames[$name] = $description;
+ }
+ }
+ }
+ return $shareNames;
+ }
}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php b/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php
index 88ab046ef38..e9349716430 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/RawConnection.php
@@ -88,7 +88,7 @@ class RawConnection {
/**
* read a line of output
*
- * @return string
+ * @return string|false
*/
public function readLine() {
return stream_get_line($this->getOutputStream(), 4086, "\n");
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Server.php b/apps/files_external/3rdparty/icewind/smb/src/Server.php
index 25f17201397..12692eb4c6e 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/Server.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/Server.php
@@ -135,32 +135,11 @@ class Server {
$connection = new RawConnection($command);
$connection->writeAuthentication($this->getUser(), $this->getPassword());
$output = $connection->readAll();
+ $parser = new Parser($this->timezoneProvider);
- $line = $output[0];
+ $parser->checkConnectionError($output[0]);
- $line = rtrim($line, ')');
- if (substr($line, -23) === ErrorCodes::LogonFailure) {
- throw new AuthenticationException();
- }
- if (substr($line, -26) === ErrorCodes::BadHostName) {
- throw new InvalidHostException();
- }
- if (substr($line, -22) === ErrorCodes::Unsuccessful) {
- throw new InvalidHostException();
- }
- if (substr($line, -28) === ErrorCodes::ConnectionRefused) {
- throw new InvalidHostException();
- }
-
- $shareNames = array();
- foreach ($output as $line) {
- if (strpos($line, '|')) {
- list($type, $name, $description) = explode('|', $line);
- if (strtolower($type) === 'disk') {
- $shareNames[$name] = $description;
- }
- }
- }
+ $shareNames = $parser->parseListShares($output);
$shares = array();
foreach ($shareNames as $name => $description) {
@@ -174,7 +153,7 @@ class Server {
* @return \Icewind\SMB\IShare
*/
public function getShare($name) {
- return new Share($this, $name);
+ return new Share($this, $name, $this->system);
}
/**
diff --git a/apps/files_external/3rdparty/icewind/smb/src/Share.php b/apps/files_external/3rdparty/icewind/smb/src/Share.php
index 21f8fe5b139..ba8bbbbb8ca 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/Share.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/Share.php
@@ -8,6 +8,7 @@
namespace Icewind\SMB;
use Icewind\SMB\Exception\ConnectionException;
+use Icewind\SMB\Exception\DependencyException;
use Icewind\SMB\Exception\FileInUseException;
use Icewind\SMB\Exception\InvalidTypeException;
use Icewind\SMB\Exception\NotFoundException;
@@ -42,24 +43,30 @@ class Share extends AbstractShare {
/**
* @param Server $server
* @param string $name
+ * @param System $system
*/
- public function __construct($server, $name) {
+ public function __construct($server, $name, System $system = null) {
parent::__construct();
$this->server = $server;
$this->name = $name;
- $this->system = new System();
+ $this->system = (!is_null($system)) ? $system : new System();
$this->parser = new Parser(new TimeZoneProvider($this->server->getHost(), $this->system));
}
protected function getConnection() {
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
- $command = sprintf('stdbuf -o0 %s %s --authentication-file=%s %s',
+ $smbClientPath = $this->system->getSmbclientPath();
+ if (!$smbClientPath) {
+ throw new DependencyException('Can\'t find smbclient binary in path');
+ }
+ $command = sprintf('%s%s %s --authentication-file=%s %s',
+ $this->system->hasStdBuf() ? 'stdbuf -o0 ' : '',
$this->system->getSmbclientPath(),
$workgroupArgument,
System::getFD(3),
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
);
- $connection = new Connection($command);
+ $connection = new Connection($command, $this->parser);
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
if (!$connection->isValid()) {
throw new ConnectionException();
@@ -97,8 +104,8 @@ class Share extends AbstractShare {
}
protected function simpleCommand($command, $path) {
- $path = $this->escapePath($path);
- $cmd = $command . ' ' . $path;
+ $escapedPath = $this->escapePath($path);
+ $cmd = $command . ' ' . $escapedPath;
$output = $this->execute($cmd);
return $this->parseOutput($output, $path);
}
@@ -125,7 +132,7 @@ class Share extends AbstractShare {
/**
* @param string $path
- * @return \Icewind\SMB\IFileInfo[]
+ * @return \Icewind\SMB\IFileInfo
*/
public function stat($path) {
$escapedPath = $this->escapePath($path);
@@ -216,8 +223,7 @@ class Share extends AbstractShare {
public function rename($from, $to) {
$path1 = $this->escapePath($from);
$path2 = $this->escapePath($to);
- $cmd = 'rename ' . $path1 . ' ' . $path2;
- $output = $this->execute($cmd);
+ $output = $this->execute('rename ' . $path1 . ' ' . $path2);
return $this->parseOutput($output, $to);
}
@@ -268,15 +274,8 @@ class Share extends AbstractShare {
$source = $this->escapePath($source);
// since returned stream is closed by the caller we need to create a new instance
// since we can't re-use the same file descriptor over multiple calls
- $workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
- $command = sprintf('%s %s --authentication-file=%s %s',
- $this->system->getSmbclientPath(),
- $workgroupArgument,
- System::getFD(3),
- escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
- );
- $connection = new Connection($command);
- $connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
+ $connection = $this->getConnection();
+
$connection->write('get ' . $source . ' ' . System::getFD(5));
$connection->write('exit');
$fh = $connection->getFileOutputStream();
@@ -297,17 +296,9 @@ class Share extends AbstractShare {
$target = $this->escapePath($target);
// since returned stream is closed by the caller we need to create a new instance
// since we can't re-use the same file descriptor over multiple calls
- $workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
- $command = sprintf('%s %s --authentication-file=%s %s',
- $this->system->getSmbclientPath(),
- $workgroupArgument,
- System::getFD(3),
- escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
- );
- $connection = new Connection($command);
- $connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
- $fh = $connection->getFileInputStream();
+ $connection = $this->getConnection();
+ $fh = $connection->getFileInputStream();
$connection->write('put ' . System::getFD(4) . ' ' . $target);
$connection->write('exit');
@@ -343,30 +334,30 @@ class Share extends AbstractShare {
$output = $this->execute($cmd);
$this->parseOutput($output, $path);
- // then set the modes we want
- $cmd = 'setmode ' . $path . ' ' . $modeString;
- $output = $this->execute($cmd);
- return $this->parseOutput($output, $path);
+ if ($mode !== FileInfo::MODE_NORMAL) {
+ // then set the modes we want
+ $cmd = 'setmode ' . $path . ' ' . $modeString;
+ $output = $this->execute($cmd);
+ return $this->parseOutput($output, $path);
+ } else {
+ return true;
+ }
}
/**
* @param string $path
- * @param callable $callback callable which will be called for each received change
- * @return mixed
+ * @return INotifyHandler
+ * @throws ConnectionException
+ * @throws DependencyException
*/
- public function notify($path, callable $callback) {
+ public function notify($path) {
+ if (!$this->system->hasStdBuf()) { //stdbuf is required to disable smbclient's output buffering
+ throw new DependencyException('stdbuf is required for usage of the notify command');
+ }
$connection = $this->getConnection(); // use a fresh connection since the notify command blocks the process
$command = 'notify ' . $this->escapePath($path);
$connection->write($command . PHP_EOL);
- $connection->read(function ($line) use ($callback, $path) {
- $code = (int)substr($line, 0, 4);
- $subPath = substr($line, 5);
- if ($path === '') {
- return $callback($code, $subPath);
- } else {
- return $callback($code, $path . '/' . $subPath);
- }
- });
+ return new NotifyHandler($connection, $path);
}
/**
@@ -395,7 +386,12 @@ class Share extends AbstractShare {
* @return bool
*/
protected function parseOutput($lines, $path = '') {
- return $this->parser->checkForError($lines, $path);
+ if (count($lines) === 0) {
+ return true;
+ } else {
+ $this->parser->checkForError($lines, $path);
+ return false;
+ }
}
/**
diff --git a/apps/files_external/3rdparty/icewind/smb/src/System.php b/apps/files_external/3rdparty/icewind/smb/src/System.php
index 192a0b3877d..7c519988aa5 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/System.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/System.php
@@ -14,6 +14,8 @@ class System {
private $net;
+ private $stdbuf;
+
public static function getFD($num) {
$folders = array(
'/proc/self/fd',
@@ -40,4 +42,14 @@ class System {
}
return $this->net;
}
+
+ public function hasStdBuf() {
+ if (!$this->stdbuf) {
+ $result = null;
+ $output = array();
+ exec('which stdbuf 2>&1', $output, $result);
+ $this->stdbuf = $result === 0;
+ }
+ return $this->stdbuf;
+ }
}
diff --git a/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php b/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php
index 86d7859a6f7..fcdf7e3e879 100644
--- a/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php
+++ b/apps/files_external/3rdparty/icewind/smb/src/TimeZoneProvider.php
@@ -27,7 +27,7 @@ class TimeZoneProvider {
* @param string $host
* @param System $system
*/
- function __construct($host, System $system) {
+ public function __construct($host, System $system) {
$this->host = $host;
$this->system = $system;
}