update icewind/smb to 1.0.5

This commit is contained in:
Robin Appelman 2016-02-09 17:09:30 +01:00
parent 2982017682
commit 3982c8f87a
16 changed files with 216 additions and 39 deletions

View File

@ -8,7 +8,7 @@
"classmap-authoritative": true
},
"require": {
"icewind/smb": "1.0.4",
"icewind/smb": "1.0.5",
"icewind/streams": "0.2"
}
}

View File

@ -4,20 +4,21 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "5c612406bc1235075305b09a5d6996a9",
"hash": "669663944c7232473a1c51a6d160319d",
"content-hash": "7612ced4391f6287fb3e50534500d217",
"packages": [
{
"name": "icewind/smb",
"version": "v1.0.4",
"version": "v1.0.5",
"source": {
"type": "git",
"url": "https://github.com/icewind1991/SMB.git",
"reference": "9277bd20262a01b38a33cc7356e98055f2262d32"
"reference": "acb94a0a85290d653cd64c883175b855ada5022f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/icewind1991/SMB/zipball/9277bd20262a01b38a33cc7356e98055f2262d32",
"reference": "9277bd20262a01b38a33cc7356e98055f2262d32",
"url": "https://api.github.com/repos/icewind1991/SMB/zipball/acb94a0a85290d653cd64c883175b855ada5022f",
"reference": "acb94a0a85290d653cd64c883175b855ada5022f",
"shasum": ""
},
"require": {
@ -25,7 +26,8 @@
"php": ">=5.3"
},
"require-dev": {
"satooshi/php-coveralls": "dev-master"
"phpunit/phpunit": "^4.8",
"satooshi/php-coveralls": "v1.0.0"
},
"type": "library",
"autoload": {
@ -45,7 +47,7 @@
}
],
"description": "php wrapper for smbclient and libsmbclient-php",
"time": "2015-08-17 14:20:38"
"time": "2016-01-20 13:12:36"
},
{
"name": "icewind/streams",

View File

@ -0,0 +1,21 @@
Copyright (c) 2015 Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -22,6 +22,7 @@ return array(
'Icewind\\SMB\\Exception\\InvalidHostException' => $vendorDir . '/icewind/smb/src/Exception/InvalidHostException.php',
'Icewind\\SMB\\Exception\\InvalidPathException' => $vendorDir . '/icewind/smb/src/Exception/InvalidPathException.php',
'Icewind\\SMB\\Exception\\InvalidRequestException' => $vendorDir . '/icewind/smb/src/Exception/InvalidRequestException.php',
'Icewind\\SMB\\Exception\\InvalidResourceException' => $vendorDir . '/icewind/smb/src/Exception/InvalidResourceException.php',
'Icewind\\SMB\\Exception\\InvalidTypeException' => $vendorDir . '/icewind/smb/src/Exception/InvalidTypeException.php',
'Icewind\\SMB\\Exception\\NoLoginServerException' => $vendorDir . '/icewind/smb/src/Exception/NoLoginServerException.php',
'Icewind\\SMB\\Exception\\NoRouteToHostException' => $vendorDir . '/icewind/smb/src/Exception/NoRouteToHostException.php',
@ -40,6 +41,14 @@ return array(
'Icewind\\SMB\\RawConnection' => $vendorDir . '/icewind/smb/src/RawConnection.php',
'Icewind\\SMB\\Server' => $vendorDir . '/icewind/smb/src/Server.php',
'Icewind\\SMB\\Share' => $vendorDir . '/icewind/smb/src/Share.php',
'Icewind\\SMB\\System' => $vendorDir . '/icewind/smb/src/System.php',
'Icewind\\SMB\\Test\\AbstractShare' => $vendorDir . '/icewind/smb/tests/AbstractShare.php',
'Icewind\\SMB\\Test\\NativeShare' => $vendorDir . '/icewind/smb/tests/NativeShare.php',
'Icewind\\SMB\\Test\\NativeStream' => $vendorDir . '/icewind/smb/tests/NativeStream.php',
'Icewind\\SMB\\Test\\Parser' => $vendorDir . '/icewind/smb/tests/Parser.php',
'Icewind\\SMB\\Test\\Server' => $vendorDir . '/icewind/smb/tests/Server.php',
'Icewind\\SMB\\Test\\Share' => $vendorDir . '/icewind/smb/tests/Share.php',
'Icewind\\SMB\\Test\\TestCase' => $vendorDir . '/icewind/smb/tests/TestCase.php',
'Icewind\\SMB\\TimeZoneProvider' => $vendorDir . '/icewind/smb/src/TimeZoneProvider.php',
'Icewind\\Streams\\CallbackWrapper' => $vendorDir . '/icewind/streams/src/CallbackWrapper.php',
'Icewind\\Streams\\Directory' => $vendorDir . '/icewind/streams/src/Directory.php',

View File

@ -43,17 +43,17 @@
},
{
"name": "icewind/smb",
"version": "v1.0.4",
"version_normalized": "1.0.4.0",
"version": "v1.0.5",
"version_normalized": "1.0.5.0",
"source": {
"type": "git",
"url": "https://github.com/icewind1991/SMB.git",
"reference": "9277bd20262a01b38a33cc7356e98055f2262d32"
"reference": "acb94a0a85290d653cd64c883175b855ada5022f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/icewind1991/SMB/zipball/9277bd20262a01b38a33cc7356e98055f2262d32",
"reference": "9277bd20262a01b38a33cc7356e98055f2262d32",
"url": "https://api.github.com/repos/icewind1991/SMB/zipball/acb94a0a85290d653cd64c883175b855ada5022f",
"reference": "acb94a0a85290d653cd64c883175b855ada5022f",
"shasum": ""
},
"require": {
@ -61,9 +61,10 @@
"php": ">=5.3"
},
"require-dev": {
"satooshi/php-coveralls": "dev-master"
"phpunit/phpunit": "^4.8",
"satooshi/php-coveralls": "v1.0.0"
},
"time": "2015-08-17 14:20:38",
"time": "2016-01-20 13:12:36",
"type": "library",
"installation-source": "source",
"autoload": {

View File

@ -13,7 +13,8 @@
"icewind/streams": "0.2.*"
},
"require-dev": {
"satooshi/php-coveralls" : "dev-master"
"satooshi/php-coveralls" : "v1.0.0",
"phpunit/phpunit": "^4.8"
},
"autoload" : {
"psr-4": {

View File

@ -39,13 +39,22 @@ class Connection extends RawConnection {
if (!$this->isValid()) {
throw new ConnectionException('Connection not valid');
}
$line = $this->readLine(); //first line is prompt
$this->checkConnectionError($line);
$promptLine = $this->readLine(); //first line is prompt
$this->checkConnectionError($promptLine);
$output = array();
$line = $this->readLine();
if ($line === false) {
throw new ConnectException('Unknown error');
if ($promptLine) { //maybe we have some error we missed on the previous line
throw new ConnectException('Unknown error (' . $promptLine . ')');
} else {
$error = $this->readError(); // maybe something on stderr
if ($error) {
throw new ConnectException('Unknown error (' . $error . ')');
} else {
throw new ConnectException('Unknown error');
}
}
}
$length = mb_strlen(self::DELIMITER);
while (mb_substr($line, 0, $length) !== self::DELIMITER) { //next prompt functions as delimiter

View File

@ -18,7 +18,10 @@ class InvalidRequestException extends Exception {
* @param int $code
*/
public function __construct($path, $code = 0) {
parent::__construct('Invalid request for ' . $path, $code);
$class = get_class($this);
$parts = explode('\\', $class);
$baseName = array_pop($parts);
parent::__construct('Invalid request for ' . $path . ' (' . $baseName . ')', $code);
$this->path = $path;
}

View File

@ -0,0 +1,11 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB\Exception;
class InvalidResourceException extends Exception {
}

View File

@ -7,6 +7,9 @@
namespace Icewind\SMB;
use Icewind\SMB\Exception\InvalidPathException;
use Icewind\SMB\Exception\InvalidResourceException;
class NativeShare extends AbstractShare {
/**
* @var Server $server
@ -193,11 +196,30 @@ class NativeShare extends AbstractShare {
*
* @throws \Icewind\SMB\Exception\NotFoundException
* @throws \Icewind\SMB\Exception\InvalidTypeException
* @throws \Icewind\SMB\Exception\InvalidPathException
* @throws \Icewind\SMB\Exception\InvalidResourceException
*/
public function get($source, $target) {
if (!$target) {
throw new InvalidPathException('Invalid target path: Filename cannot be empty');
}
$targetHandle = @fopen($target, 'wb');
if (!$targetHandle) {
$error = error_get_last();
if (is_array($error)) {
$reason = $error['message'];
} else {
$reason = 'Unknown error';
}
throw new InvalidResourceException('Failed opening local file "' . $target . '" for writing: ' . $reason);
}
$this->connect();
$sourceHandle = $this->state->open($this->buildUrl($source), 'r');
$targetHandle = fopen($target, 'wb');
if (!$sourceHandle) {
fclose($targetHandle);
throw new InvalidResourceException('Failed opening remote file "' . $source . '" for reading');
}
while ($data = $this->state->read($sourceHandle, 4096)) {
fwrite($targetHandle, $data);

View File

@ -11,6 +11,7 @@ use Icewind\SMB\Exception\AccessDeniedException;
use Icewind\SMB\Exception\AlreadyExistsException;
use Icewind\SMB\Exception\Exception;
use Icewind\SMB\Exception\FileInUseException;
use Icewind\SMB\Exception\InvalidResourceException;
use Icewind\SMB\Exception\InvalidTypeException;
use Icewind\SMB\Exception\NotEmptyException;
use Icewind\SMB\Exception\NotFoundException;
@ -42,6 +43,13 @@ class Parser {
$error = $part;
}
}
$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');
}
switch ($error) {
case ErrorCodes::PathNotFound:
case ErrorCodes::ObjectNotFound:

View File

@ -94,6 +94,15 @@ class RawConnection {
return stream_get_line($this->getOutputStream(), 4086, "\n");
}
/**
* read a line of output
*
* @return string
*/
public function readError() {
return trim(stream_get_line($this->getErrorStream(), 4086));
}
/**
* get all output until the process closes
*

View File

@ -11,7 +11,6 @@ use Icewind\SMB\Exception\AuthenticationException;
use Icewind\SMB\Exception\InvalidHostException;
class Server {
const CLIENT = 'smbclient';
const LOCALE = 'en_US.UTF-8';
/**
@ -34,6 +33,16 @@ class Server {
*/
protected $workgroup;
/**
* @var \Icewind\SMB\System
*/
private $system;
/**
* @var TimeZoneProvider
*/
private $timezoneProvider;
/**
* Check if the smbclient php extension is available
*
@ -54,6 +63,8 @@ class Server {
$this->user = $user;
$this->workgroup = $workgroup;
$this->password = $password;
$this->system = new System();
$this->timezoneProvider = new TimeZoneProvider($host, $this->system);
}
/**
@ -115,8 +126,12 @@ class Server {
*/
public function listShares() {
$workgroupArgument = ($this->workgroup) ? ' -W ' . escapeshellarg($this->workgroup) : '';
$command = Server::CLIENT . $workgroupArgument . ' --authentication-file=/proc/self/fd/3' .
' -gL ' . escapeshellarg($this->getHost());
$command = sprintf('%s %s --authentication-file=%s -gL %s',
$this->system->getSmbclientPath(),
$workgroupArgument,
System::getFD(3),
escapeshellarg($this->getHost())
);
$connection = new RawConnection($command);
$connection->writeAuthentication($this->getUser(), $this->getPassword());
$output = $connection->readAll();
@ -166,7 +181,6 @@ class Server {
* @return string
*/
public function getTimeZone() {
$command = 'net time zone -S ' . escapeshellarg($this->getHost());
return exec($command);
return $this->timezoneProvider->get();
}
}

View File

@ -34,6 +34,11 @@ class Share extends AbstractShare {
*/
protected $parser;
/**
* @var \Icewind\SMB\System
*/
private $system;
/**
* @param Server $server
* @param string $name
@ -42,7 +47,8 @@ class Share extends AbstractShare {
parent::__construct();
$this->server = $server;
$this->name = $name;
$this->parser = new Parser(new TimeZoneProvider($this->server->getHost()));
$this->system = new System();
$this->parser = new Parser(new TimeZoneProvider($this->server->getHost(), $this->system));
}
/**
@ -55,9 +61,10 @@ class Share extends AbstractShare {
return;
}
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s',
Server::CLIENT,
$command = sprintf('%s %s --authentication-file=%s %s',
$this->system->getSmbclientPath(),
$workgroupArgument,
System::getFD(3),
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
);
$this->connection = new Connection($command);
@ -257,14 +264,15 @@ class Share extends AbstractShare {
// 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=/proc/self/fd/3 %s',
Server::CLIENT,
$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->write('get ' . $source . ' /proc/self/fd/5');
$connection->write('get ' . $source . ' ' . System::getFD(5));
$connection->write('exit');
$fh = $connection->getFileOutputStream();
stream_context_set_option($fh, 'file', 'connection', $connection);
@ -285,16 +293,17 @@ class Share extends AbstractShare {
// 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=/proc/self/fd/3 %s',
Server::CLIENT,
$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->write('put /proc/self/fd/4 ' . $target);
$connection->write('put ' . System::getFD(4) . ' ' . $target);
$connection->write('exit');
// use a close callback to ensure the upload is finished before continuing

View File

@ -0,0 +1,43 @@
<?php
/**
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\SMB;
use Icewind\SMB\Exception\Exception;
class System {
private $smbclient;
private $net;
public static function getFD($num) {
$folders = array(
'/proc/self/fd',
'/dev/fd'
);
foreach ($folders as $folder) {
if (file_exists($folder)) {
return $folder . '/' . $num;
}
}
throw new Exception('Cant find file descriptor path');
}
public function getSmbclientPath() {
if (!$this->smbclient) {
$this->smbclient = trim(`which smbclient`);
}
return $this->smbclient;
}
public function getNetPath() {
if (!$this->net) {
$this->net = trim(`which net`);
}
return $this->net;
}
}

View File

@ -19,16 +19,31 @@ class TimeZoneProvider {
private $timeZone;
/**
* @param string $host
* @var System
*/
function __construct($host) {
private $system;
/**
* @param string $host
* @param System $system
*/
function __construct($host, System $system) {
$this->host = $host;
$this->system = $system;
}
public function get() {
if (!$this->timeZone) {
$command = 'net time zone -S ' . escapeshellarg($this->host);
$this->timeZone = exec($command);
$net = $this->system->getNetPath();
if ($net) {
$command = sprintf('%s time zone -S %s',
$net,
escapeshellarg($this->host)
);
$this->timeZone = exec($command);
} else { // fallback to server timezone
$this->timeZone = date_default_timezone_get();
}
}
return $this->timeZone;
}