mirror of
https://codeberg.org/icewind/SMB.git
synced 2026-06-03 17:24:07 +02:00
more type hints
This commit is contained in:
parent
767f6b3f6f
commit
e9f6d00a93
28 changed files with 343 additions and 530 deletions
|
|
@ -54,7 +54,7 @@ abstract class AbstractServer implements IServer {
|
||||||
* @param ITimeZoneProvider $timeZoneProvider
|
* @param ITimeZoneProvider $timeZoneProvider
|
||||||
* @param IOptions $options
|
* @param IOptions $options
|
||||||
*/
|
*/
|
||||||
public function __construct($host, IAuth $auth, ISystem $system, ITimeZoneProvider $timeZoneProvider, IOptions $options) {
|
public function __construct(string $host, IAuth $auth, ISystem $system, ITimeZoneProvider $timeZoneProvider, IOptions $options) {
|
||||||
$this->host = $host;
|
$this->host = $host;
|
||||||
$this->auth = $auth;
|
$this->auth = $auth;
|
||||||
$this->system = $system;
|
$this->system = $system;
|
||||||
|
|
@ -62,23 +62,23 @@ abstract class AbstractServer implements IServer {
|
||||||
$this->options = $options;
|
$this->options = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAuth() {
|
public function getAuth(): IAuth {
|
||||||
return $this->auth;
|
return $this->auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHost() {
|
public function getHost(): string {
|
||||||
return $this->host;
|
return $this->host;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTimeZone() {
|
public function getTimeZone(): string {
|
||||||
return $this->timezoneProvider->get($this->host);
|
return $this->timezoneProvider->get($this->host);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSystem() {
|
public function getSystem(): ISystem {
|
||||||
return $this->system;
|
return $this->system;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOptions() {
|
public function getOptions(): IOptions {
|
||||||
return $this->options;
|
return $this->options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,19 +22,19 @@
|
||||||
namespace Icewind\SMB;
|
namespace Icewind\SMB;
|
||||||
|
|
||||||
class AnonymousAuth implements IAuth {
|
class AnonymousAuth implements IAuth {
|
||||||
public function getUsername() {
|
public function getUsername(): ?string {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getWorkgroup() {
|
public function getWorkgroup(): ?string {
|
||||||
return 'dummy';
|
return 'dummy';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPassword() {
|
public function getPassword(): ?string {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExtraCommandLineArguments() {
|
public function getExtraCommandLineArguments(): string {
|
||||||
return '-N';
|
return '-N';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,32 +29,25 @@ class BasicAuth implements IAuth {
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $password;
|
private $password;
|
||||||
|
|
||||||
/**
|
public function __construct(string $username, string $workgroup, string $password) {
|
||||||
* BasicAuth constructor.
|
|
||||||
*
|
|
||||||
* @param string $username
|
|
||||||
* @param string $workgroup
|
|
||||||
* @param string $password
|
|
||||||
*/
|
|
||||||
public function __construct($username, $workgroup, $password) {
|
|
||||||
$this->username = $username;
|
$this->username = $username;
|
||||||
$this->workgroup = $workgroup;
|
$this->workgroup = $workgroup;
|
||||||
$this->password = $password;
|
$this->password = $password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUsername() {
|
public function getUsername(): ?string {
|
||||||
return $this->username;
|
return $this->username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getWorkgroup() {
|
public function getWorkgroup(): ?string {
|
||||||
return $this->workgroup;
|
return $this->workgroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPassword() {
|
public function getPassword(): ?string {
|
||||||
return $this->password;
|
return $this->password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExtraCommandLineArguments() {
|
public function getExtraCommandLineArguments(): string {
|
||||||
return ($this->workgroup) ? '-W ' . escapeshellarg($this->workgroup) : '';
|
return ($this->workgroup) ? '-W ' . escapeshellarg($this->workgroup) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
namespace Icewind\SMB\Exception;
|
namespace Icewind\SMB\Exception;
|
||||||
|
|
||||||
class Exception extends \Exception {
|
class Exception extends \Exception {
|
||||||
public static function unknown($path, $error) {
|
public static function unknown(?string $path, $error) {
|
||||||
$message = 'Unknown error (' . $error . ')';
|
$message = 'Unknown error (' . $error . ')';
|
||||||
if ($path) {
|
if ($path) {
|
||||||
$message .= ' for ' . $path;
|
$message .= ' for ' . $path;
|
||||||
|
|
@ -17,13 +17,7 @@ class Exception extends \Exception {
|
||||||
return new Exception($message, is_string($error) ? 0 : $error);
|
return new Exception($message, is_string($error) ? 0 : $error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static function fromMap(array $exceptionMap, $error, ?string $path): Exception {
|
||||||
* @param array $exceptionMap
|
|
||||||
* @param mixed $error
|
|
||||||
* @param string $path
|
|
||||||
* @return Exception
|
|
||||||
*/
|
|
||||||
public static function fromMap(array $exceptionMap, $error, $path) {
|
|
||||||
if (isset($exceptionMap[$error])) {
|
if (isset($exceptionMap[$error])) {
|
||||||
$exceptionClass = $exceptionMap[$error];
|
$exceptionClass = $exceptionMap[$error];
|
||||||
if (is_numeric($error)) {
|
if (is_numeric($error)) {
|
||||||
|
|
|
||||||
|
|
@ -22,27 +22,18 @@
|
||||||
namespace Icewind\SMB;
|
namespace Icewind\SMB;
|
||||||
|
|
||||||
interface IAuth {
|
interface IAuth {
|
||||||
/**
|
public function getUsername(): ?string;
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getUsername();
|
|
||||||
|
|
||||||
/**
|
public function getWorkgroup(): ?string;
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getWorkgroup();
|
|
||||||
|
|
||||||
/**
|
public function getPassword(): ?string;
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getPassword();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any extra command line option for smbclient that are required
|
* Any extra command line option for smbclient that are required
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getExtraCommandLineArguments();
|
public function getExtraCommandLineArguments(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set any extra options for libsmbclient that are required
|
* Set any extra options for libsmbclient that are required
|
||||||
|
|
|
||||||
|
|
@ -21,50 +21,23 @@ interface IFileInfo {
|
||||||
const MODE_ARCHIVE = 0x20;
|
const MODE_ARCHIVE = 0x20;
|
||||||
const MODE_NORMAL = 0x80;
|
const MODE_NORMAL = 0x80;
|
||||||
|
|
||||||
/**
|
public function getPath(): string;
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getPath();
|
|
||||||
|
|
||||||
/**
|
public function getName(): string;
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getName();
|
|
||||||
|
|
||||||
/**
|
public function getSize(): int;
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getSize();
|
|
||||||
|
|
||||||
/**
|
public function getMTime(): int;
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getMTime();
|
|
||||||
|
|
||||||
/**
|
public function isDirectory(): bool;
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isDirectory();
|
|
||||||
|
|
||||||
/**
|
public function isReadOnly(): bool;
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isReadOnly();
|
|
||||||
|
|
||||||
/**
|
public function isHidden(): bool;
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isHidden();
|
|
||||||
|
|
||||||
/**
|
public function isSystem(): bool;
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isSystem();
|
|
||||||
|
|
||||||
/**
|
public function isArchived(): bool;
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isArchived();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ACL[]
|
* @return ACL[]
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ interface INotifyHandler {
|
||||||
*
|
*
|
||||||
* @return Change[]
|
* @return Change[]
|
||||||
*/
|
*/
|
||||||
public function getChanges();
|
public function getChanges(): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen actively to all incoming changes
|
* Listen actively to all incoming changes
|
||||||
|
|
@ -34,7 +34,7 @@ interface INotifyHandler {
|
||||||
*
|
*
|
||||||
* @param callable $callback
|
* @param callable $callback
|
||||||
*/
|
*/
|
||||||
public function listen($callback);
|
public function listen(callable $callback): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop listening for changes
|
* Stop listening for changes
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,9 @@
|
||||||
namespace Icewind\SMB;
|
namespace Icewind\SMB;
|
||||||
|
|
||||||
interface IServer {
|
interface IServer {
|
||||||
/**
|
public function getAuth(): IAuth;
|
||||||
* @return IAuth
|
|
||||||
*/
|
|
||||||
public function getAuth();
|
|
||||||
|
|
||||||
/**
|
public function getHost(): string;
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getHost();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Icewind\SMB\IShare[]
|
* @return \Icewind\SMB\IShare[]
|
||||||
|
|
@ -38,32 +32,15 @@ interface IServer {
|
||||||
* @throws \Icewind\SMB\Exception\AuthenticationException
|
* @throws \Icewind\SMB\Exception\AuthenticationException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidHostException
|
* @throws \Icewind\SMB\Exception\InvalidHostException
|
||||||
*/
|
*/
|
||||||
public function listShares();
|
public function listShares(): array;
|
||||||
|
|
||||||
/**
|
public function getShare(string $name): IShare;
|
||||||
* @param string $name
|
|
||||||
* @return \Icewind\SMB\IShare
|
|
||||||
*/
|
|
||||||
public function getShare($name);
|
|
||||||
|
|
||||||
/**
|
public function getTimeZone(): string;
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getTimeZone();
|
|
||||||
|
|
||||||
/**
|
public function getSystem(): ISystem;
|
||||||
* @return ISystem
|
|
||||||
*/
|
|
||||||
public function getSystem();
|
|
||||||
|
|
||||||
/**
|
public function getOptions(): IOptions;
|
||||||
* @return IOptions
|
|
||||||
*/
|
|
||||||
public function getOptions();
|
|
||||||
|
|
||||||
/**
|
public static function available(ISystem $system): bool;
|
||||||
* @param ISystem $system
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function available(ISystem $system);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,18 @@
|
||||||
|
|
||||||
namespace Icewind\SMB;
|
namespace Icewind\SMB;
|
||||||
|
|
||||||
|
use Icewind\SMB\Exception\AlreadyExistsException;
|
||||||
|
use Icewind\SMB\Exception\InvalidRequestException;
|
||||||
|
use Icewind\SMB\Exception\InvalidTypeException;
|
||||||
|
use Icewind\SMB\Exception\NotFoundException;
|
||||||
|
|
||||||
interface IShare {
|
interface IShare {
|
||||||
/**
|
/**
|
||||||
* Get the name of the share
|
* Get the name of the share
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getName();
|
public function getName(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download a remote file
|
* Download a remote file
|
||||||
|
|
@ -22,10 +27,10 @@ interface IShare {
|
||||||
* @param string $target local file
|
* @param string $target local file
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function get($source, $target);
|
public function get(string $source, string $target): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload a local file
|
* Upload a local file
|
||||||
|
|
@ -34,10 +39,10 @@ interface IShare {
|
||||||
* @param string $target remove file
|
* @param string $target remove file
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function put($source, $target);
|
public function put(string $source, string $target): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a readable stream top a remote file
|
* Open a readable stream top a remote file
|
||||||
|
|
@ -45,10 +50,10 @@ interface IShare {
|
||||||
* @param string $source
|
* @param string $source
|
||||||
* @return resource a read only stream with the contents of the remote file
|
* @return resource a read only stream with the contents of the remote file
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function read($source);
|
public function read(string $source);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a writable stream to a remote file
|
* Open a writable stream to a remote file
|
||||||
|
|
@ -57,10 +62,10 @@ interface IShare {
|
||||||
* @param string $target
|
* @param string $target
|
||||||
* @return resource a write only stream to upload a remote file
|
* @return resource a write only stream to upload a remote file
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function write($target);
|
public function write(string $target);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a writable stream to a remote file and set the cursor to the end of the file
|
* Open a writable stream to a remote file and set the cursor to the end of the file
|
||||||
|
|
@ -68,11 +73,11 @@ interface IShare {
|
||||||
* @param string $target
|
* @param string $target
|
||||||
* @return resource a write only stream to upload a remote file
|
* @return resource a write only stream to upload a remote file
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidRequestException
|
* @throws InvalidRequestException
|
||||||
*/
|
*/
|
||||||
public function append($target);
|
public function append(string $target);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename a remote file
|
* Rename a remote file
|
||||||
|
|
@ -81,10 +86,10 @@ interface IShare {
|
||||||
* @param string $to
|
* @param string $to
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\AlreadyExistsException
|
* @throws AlreadyExistsException
|
||||||
*/
|
*/
|
||||||
public function rename($from, $to);
|
public function rename(string $from, string $to): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a file on the share
|
* Delete a file on the share
|
||||||
|
|
@ -92,29 +97,29 @@ interface IShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function del($path);
|
public function del(string $path): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List the content of a remote folder
|
* List the content of a remote folder
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return \Icewind\SMB\IFileInfo[]
|
* @return IFileInfo[]
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function dir($path);
|
public function dir(string $path): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return \Icewind\SMB\IFileInfo
|
* @return IFileInfo
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
public function stat($path);
|
public function stat(string $path): IFileInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a folder on the share
|
* Create a folder on the share
|
||||||
|
|
@ -122,10 +127,10 @@ interface IShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\AlreadyExistsException
|
* @throws AlreadyExistsException
|
||||||
*/
|
*/
|
||||||
public function mkdir($path);
|
public function mkdir(string $path): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a folder on the share
|
* Remove a folder on the share
|
||||||
|
|
@ -133,23 +138,23 @@ interface IShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function rmdir($path);
|
public function rmdir(string $path): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
|
* @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function setMode($path, $mode);
|
public function setMode(string $path, int $mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return INotifyHandler
|
* @return INotifyHandler
|
||||||
*/
|
*/
|
||||||
public function notify($path);
|
public function notify(string $path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the IServer instance for this share
|
* Get the IServer instance for this share
|
||||||
|
|
|
||||||
|
|
@ -32,47 +32,47 @@ interface ISystem {
|
||||||
* @param int $num the file descriptor id
|
* @param int $num the file descriptor id
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFD($num);
|
public function getFD(int $num): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the full path to the `smbclient` binary of false if the binary is not available
|
* Get the full path to the `smbclient` binary of null if the binary is not available
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function getSmbclientPath();
|
public function getSmbclientPath(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the full path to the `net` binary of false if the binary is not available
|
* Get the full path to the `net` binary of null if the binary is not available
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function getNetPath();
|
public function getNetPath(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the full path to the `smbcacls` binary of false if the binary is not available
|
* Get the full path to the `smbcacls` binary of null if the binary is not available
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function getSmbcAclsPath();
|
public function getSmbcAclsPath(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the full path to the `stdbuf` binary of false if the binary is not available
|
* Get the full path to the `stdbuf` binary of null if the binary is not available
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function getStdBufPath();
|
public function getStdBufPath(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the full path to the `date` binary of false if the binary is not available
|
* Get the full path to the `date` binary of null if the binary is not available
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|null
|
||||||
*/
|
*/
|
||||||
public function getDatePath();
|
public function getDatePath(): ?string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the smbclient php extension is enabled
|
* Whether or not the smbclient php extension is enabled
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function libSmbclientAvailable();
|
public function libSmbclientAvailable(): bool;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,5 @@ interface ITimeZoneProvider {
|
||||||
* @param string $host
|
* @param string $host
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function get($host);
|
public function get(string $host): string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,19 +25,19 @@ namespace Icewind\SMB;
|
||||||
* Use existing kerberos ticket to authenticate
|
* Use existing kerberos ticket to authenticate
|
||||||
*/
|
*/
|
||||||
class KerberosAuth implements IAuth {
|
class KerberosAuth implements IAuth {
|
||||||
public function getUsername() {
|
public function getUsername(): ?string {
|
||||||
return 'dummy';
|
return 'dummy';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getWorkgroup() {
|
public function getWorkgroup(): ?string {
|
||||||
return 'dummy';
|
return 'dummy';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPassword() {
|
public function getPassword(): ?string {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExtraCommandLineArguments() {
|
public function getExtraCommandLineArguments(): string {
|
||||||
return '-k';
|
return '-k';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,55 +11,30 @@ use Icewind\SMB\ACL;
|
||||||
use Icewind\SMB\IFileInfo;
|
use Icewind\SMB\IFileInfo;
|
||||||
|
|
||||||
class NativeFileInfo implements IFileInfo {
|
class NativeFileInfo implements IFileInfo {
|
||||||
/**
|
/** @var string */
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $path;
|
protected $path;
|
||||||
|
/** @var string */
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $name;
|
protected $name;
|
||||||
|
/** @var NativeShare */
|
||||||
/**
|
|
||||||
* @var NativeShare
|
|
||||||
*/
|
|
||||||
protected $share;
|
protected $share;
|
||||||
|
/** @var array|null */
|
||||||
/**
|
|
||||||
* @var array|null
|
|
||||||
*/
|
|
||||||
protected $attributeCache = null;
|
protected $attributeCache = null;
|
||||||
|
|
||||||
/**
|
public function __construct(NativeShare $share, string $path, string $name) {
|
||||||
* @param NativeShare $share
|
|
||||||
* @param string $path
|
|
||||||
* @param string $name
|
|
||||||
*/
|
|
||||||
public function __construct($share, $path, $name) {
|
|
||||||
$this->share = $share;
|
$this->share = $share;
|
||||||
$this->path = $path;
|
$this->path = $path;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getPath(): string {
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getPath() {
|
|
||||||
return $this->path;
|
return $this->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getName(): string {
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getName() {
|
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function stat(): array {
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function stat() {
|
|
||||||
if (is_null($this->attributeCache)) {
|
if (is_null($this->attributeCache)) {
|
||||||
$rawAttributes = explode(',', $this->share->getAttribute($this->path, 'system.dos_attr.*'));
|
$rawAttributes = explode(',', $this->share->getAttribute($this->path, 'system.dos_attr.*'));
|
||||||
$this->attributeCache = [];
|
$this->attributeCache = [];
|
||||||
|
|
@ -76,18 +51,12 @@ class NativeFileInfo implements IFileInfo {
|
||||||
return $this->attributeCache;
|
return $this->attributeCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getSize(): int {
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getSize() {
|
|
||||||
$stat = $this->stat();
|
$stat = $this->stat();
|
||||||
return $stat['size'];
|
return $stat['size'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getMTime(): int {
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getMTime() {
|
|
||||||
$stat = $this->stat();
|
$stat = $this->stat();
|
||||||
return $stat['write_time'];
|
return $stat['write_time'];
|
||||||
}
|
}
|
||||||
|
|
@ -104,10 +73,7 @@ class NativeFileInfo implements IFileInfo {
|
||||||
* as false (except for `hidden` where we use the unix dotfile convention)
|
* as false (except for `hidden` where we use the unix dotfile convention)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
protected function getMode(): int {
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
protected function getMode() {
|
|
||||||
$mode = $this->stat()['mode'];
|
$mode = $this->stat()['mode'];
|
||||||
|
|
||||||
// Let us ignore the ATTR_NOT_CONTENT_INDEXED for now
|
// Let us ignore the ATTR_NOT_CONTENT_INDEXED for now
|
||||||
|
|
@ -116,10 +82,7 @@ class NativeFileInfo implements IFileInfo {
|
||||||
return $mode;
|
return $mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isDirectory(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isDirectory() {
|
|
||||||
$mode = $this->getMode();
|
$mode = $this->getMode();
|
||||||
if ($mode > 0x1000) {
|
if ($mode > 0x1000) {
|
||||||
return (bool)($mode & 0x4000); // 0x4000: unix directory flag
|
return (bool)($mode & 0x4000); // 0x4000: unix directory flag
|
||||||
|
|
@ -128,10 +91,7 @@ class NativeFileInfo implements IFileInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isReadOnly(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isReadOnly() {
|
|
||||||
$mode = $this->getMode();
|
$mode = $this->getMode();
|
||||||
if ($mode > 0x1000) {
|
if ($mode > 0x1000) {
|
||||||
return !(bool)($mode & 0x80); // 0x80: owner write permissions
|
return !(bool)($mode & 0x80); // 0x80: owner write permissions
|
||||||
|
|
@ -140,10 +100,7 @@ class NativeFileInfo implements IFileInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isHidden(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isHidden() {
|
|
||||||
$mode = $this->getMode();
|
$mode = $this->getMode();
|
||||||
if ($mode > 0x1000) {
|
if ($mode > 0x1000) {
|
||||||
return strlen($this->name) > 0 && $this->name[0] === '.';
|
return strlen($this->name) > 0 && $this->name[0] === '.';
|
||||||
|
|
@ -152,10 +109,7 @@ class NativeFileInfo implements IFileInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isSystem(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isSystem() {
|
|
||||||
$mode = $this->getMode();
|
$mode = $this->getMode();
|
||||||
if ($mode > 0x1000) {
|
if ($mode > 0x1000) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -164,10 +118,7 @@ class NativeFileInfo implements IFileInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isArchived(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isArchived() {
|
|
||||||
$mode = $this->getMode();
|
$mode = $this->getMode();
|
||||||
if ($mode > 0x1000) {
|
if ($mode > 0x1000) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ namespace Icewind\SMB\Native;
|
||||||
use Icewind\SMB\AbstractServer;
|
use Icewind\SMB\AbstractServer;
|
||||||
use Icewind\SMB\IAuth;
|
use Icewind\SMB\IAuth;
|
||||||
use Icewind\SMB\IOptions;
|
use Icewind\SMB\IOptions;
|
||||||
|
use Icewind\SMB\IShare;
|
||||||
use Icewind\SMB\ISystem;
|
use Icewind\SMB\ISystem;
|
||||||
use Icewind\SMB\ITimeZoneProvider;
|
use Icewind\SMB\ITimeZoneProvider;
|
||||||
|
|
||||||
|
|
@ -19,7 +20,7 @@ class NativeServer extends AbstractServer {
|
||||||
*/
|
*/
|
||||||
protected $state;
|
protected $state;
|
||||||
|
|
||||||
public function __construct($host, IAuth $auth, ISystem $system, ITimeZoneProvider $timeZoneProvider, IOptions $options) {
|
public function __construct(string $host, IAuth $auth, ISystem $system, ITimeZoneProvider $timeZoneProvider, IOptions $options) {
|
||||||
parent::__construct($host, $auth, $system, $timeZoneProvider, $options);
|
parent::__construct($host, $auth, $system, $timeZoneProvider, $options);
|
||||||
$this->state = new NativeState();
|
$this->state = new NativeState();
|
||||||
}
|
}
|
||||||
|
|
@ -33,24 +34,20 @@ class NativeServer extends AbstractServer {
|
||||||
* @throws \Icewind\SMB\Exception\AuthenticationException
|
* @throws \Icewind\SMB\Exception\AuthenticationException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidHostException
|
* @throws \Icewind\SMB\Exception\InvalidHostException
|
||||||
*/
|
*/
|
||||||
public function listShares() {
|
public function listShares(): array {
|
||||||
$this->connect();
|
$this->connect();
|
||||||
$shares = [];
|
$shares = [];
|
||||||
$dh = $this->state->opendir('smb://' . $this->getHost());
|
$dh = $this->state->opendir('smb://' . $this->getHost());
|
||||||
while ($share = $this->state->readdir($dh)) {
|
while ($share = $this->state->readdir($dh, '')) {
|
||||||
if ($share['type'] === 'file share') {
|
if ($share['type'] === 'file share') {
|
||||||
$shares[] = $this->getShare($share['name']);
|
$shares[] = $this->getShare($share['name']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->state->closedir($dh);
|
$this->state->closedir($dh, '');
|
||||||
return $shares;
|
return $shares;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getShare(string $name): IShare {
|
||||||
* @param string $name
|
|
||||||
* @return \Icewind\SMB\IShare
|
|
||||||
*/
|
|
||||||
public function getShare($name) {
|
|
||||||
return new NativeShare($this, $name);
|
return new NativeShare($this, $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,7 +57,7 @@ class NativeServer extends AbstractServer {
|
||||||
* @param ISystem $system
|
* @param ISystem $system
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function available(ISystem $system) {
|
public static function available(ISystem $system): bool {
|
||||||
return $system->libSmbclientAvailable();
|
return $system->libSmbclientAvailable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,16 @@
|
||||||
namespace Icewind\SMB\Native;
|
namespace Icewind\SMB\Native;
|
||||||
|
|
||||||
use Icewind\SMB\AbstractShare;
|
use Icewind\SMB\AbstractShare;
|
||||||
|
use Icewind\SMB\Exception\AlreadyExistsException;
|
||||||
|
use Icewind\SMB\Exception\AuthenticationException;
|
||||||
|
use Icewind\SMB\Exception\ConnectionException;
|
||||||
use Icewind\SMB\Exception\DependencyException;
|
use Icewind\SMB\Exception\DependencyException;
|
||||||
|
use Icewind\SMB\Exception\InvalidHostException;
|
||||||
use Icewind\SMB\Exception\InvalidPathException;
|
use Icewind\SMB\Exception\InvalidPathException;
|
||||||
use Icewind\SMB\Exception\InvalidResourceException;
|
use Icewind\SMB\Exception\InvalidResourceException;
|
||||||
|
use Icewind\SMB\Exception\InvalidTypeException;
|
||||||
|
use Icewind\SMB\Exception\NotFoundException;
|
||||||
|
use Icewind\SMB\IFileInfo;
|
||||||
use Icewind\SMB\INotifyHandler;
|
use Icewind\SMB\INotifyHandler;
|
||||||
use Icewind\SMB\IServer;
|
use Icewind\SMB\IServer;
|
||||||
use Icewind\SMB\Wrapped\Server;
|
use Icewind\SMB\Wrapped\Server;
|
||||||
|
|
@ -32,22 +39,18 @@ class NativeShare extends AbstractShare {
|
||||||
*/
|
*/
|
||||||
private $state;
|
private $state;
|
||||||
|
|
||||||
/**
|
public function __construct(IServer $server, string $name) {
|
||||||
* @param IServer $server
|
|
||||||
* @param string $name
|
|
||||||
*/
|
|
||||||
public function __construct($server, $name) {
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->server = $server;
|
$this->server = $server;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \Icewind\SMB\Exception\ConnectionException
|
* @throws ConnectionException
|
||||||
* @throws \Icewind\SMB\Exception\AuthenticationException
|
* @throws AuthenticationException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidHostException
|
* @throws InvalidHostException
|
||||||
*/
|
*/
|
||||||
protected function getState() {
|
protected function getState(): NativeState {
|
||||||
if ($this->state and $this->state instanceof NativeState) {
|
if ($this->state and $this->state instanceof NativeState) {
|
||||||
return $this->state;
|
return $this->state;
|
||||||
}
|
}
|
||||||
|
|
@ -62,11 +65,11 @@ class NativeShare extends AbstractShare {
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getName() {
|
public function getName(): string {
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildUrl($path) {
|
private function buildUrl(string $path): string {
|
||||||
$this->verifyPath($path);
|
$this->verifyPath($path);
|
||||||
$url = sprintf('smb://%s/%s', $this->server->getHost(), $this->name);
|
$url = sprintf('smb://%s/%s', $this->server->getHost(), $this->name);
|
||||||
if ($path) {
|
if ($path) {
|
||||||
|
|
@ -81,16 +84,16 @@ class NativeShare extends AbstractShare {
|
||||||
* List the content of a remote folder
|
* List the content of a remote folder
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return \Icewind\SMB\IFileInfo[]
|
* @return IFileInfo[]
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function dir($path) {
|
public function dir(string $path): array {
|
||||||
$files = [];
|
$files = [];
|
||||||
|
|
||||||
$dh = $this->getState()->opendir($this->buildUrl($path));
|
$dh = $this->getState()->opendir($this->buildUrl($path));
|
||||||
while ($file = $this->getState()->readdir($dh)) {
|
while ($file = $this->getState()->readdir($dh, $path)) {
|
||||||
$name = $file['name'];
|
$name = $file['name'];
|
||||||
if ($name !== '.' and $name !== '..') {
|
if ($name !== '.' and $name !== '..') {
|
||||||
$fullPath = $path . '/' . $name;
|
$fullPath = $path . '/' . $name;
|
||||||
|
|
@ -98,15 +101,15 @@ class NativeShare extends AbstractShare {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->getState()->closedir($dh);
|
$this->getState()->closedir($dh, $path);
|
||||||
return $files;
|
return $files;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return \Icewind\SMB\IFileInfo
|
* @return IFileInfo
|
||||||
*/
|
*/
|
||||||
public function stat($path) {
|
public function stat(string $path): IFileInfo {
|
||||||
$info = new NativeFileInfo($this, $path, self::mb_basename($path));
|
$info = new NativeFileInfo($this, $path, self::mb_basename($path));
|
||||||
|
|
||||||
// trigger attribute loading
|
// trigger attribute loading
|
||||||
|
|
@ -122,7 +125,7 @@ class NativeShare extends AbstractShare {
|
||||||
* @link http://php.net/manual/en/function.basename.php#121405
|
* @link http://php.net/manual/en/function.basename.php#121405
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected static function mb_basename($path) {
|
protected static function mb_basename(string $path): string {
|
||||||
if (preg_match('@^.*[\\\\/]([^\\\\/]+)$@s', $path, $matches)) {
|
if (preg_match('@^.*[\\\\/]([^\\\\/]+)$@s', $path, $matches)) {
|
||||||
return $matches[1];
|
return $matches[1];
|
||||||
} elseif (preg_match('@^([^\\\\/]+)$@s', $path, $matches)) {
|
} elseif (preg_match('@^([^\\\\/]+)$@s', $path, $matches)) {
|
||||||
|
|
@ -138,10 +141,10 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\AlreadyExistsException
|
* @throws AlreadyExistsException
|
||||||
*/
|
*/
|
||||||
public function mkdir($path) {
|
public function mkdir(string $path): bool {
|
||||||
return $this->getState()->mkdir($this->buildUrl($path));
|
return $this->getState()->mkdir($this->buildUrl($path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,10 +154,10 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function rmdir($path) {
|
public function rmdir(string $path): bool {
|
||||||
return $this->getState()->rmdir($this->buildUrl($path));
|
return $this->getState()->rmdir($this->buildUrl($path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,10 +167,10 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function del($path) {
|
public function del(string $path): bool {
|
||||||
return $this->getState()->unlink($this->buildUrl($path));
|
return $this->getState()->unlink($this->buildUrl($path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,10 +181,10 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $to
|
* @param string $to
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\AlreadyExistsException
|
* @throws AlreadyExistsException
|
||||||
*/
|
*/
|
||||||
public function rename($from, $to) {
|
public function rename(string $from, string $to): bool{
|
||||||
return $this->getState()->rename($this->buildUrl($from), $this->buildUrl($to));
|
return $this->getState()->rename($this->buildUrl($from), $this->buildUrl($to));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,10 +195,10 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $target remove file
|
* @param string $target remove file
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function put($source, $target) {
|
public function put(string $source, string $target): bool {
|
||||||
$sourceHandle = fopen($source, 'rb');
|
$sourceHandle = fopen($source, 'rb');
|
||||||
$targetUrl = $this->buildUrl($target);
|
$targetUrl = $this->buildUrl($target);
|
||||||
|
|
||||||
|
|
@ -215,20 +218,18 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $target local file
|
* @param string $target local file
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws AuthenticationException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws ConnectionException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidPathException
|
* @throws InvalidHostException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidResourceException
|
* @throws InvalidPathException
|
||||||
|
* @throws InvalidResourceException
|
||||||
*/
|
*/
|
||||||
public function get($source, $target) {
|
public function get(string $source, string $target): bool {
|
||||||
if (!$target) {
|
if (!$target) {
|
||||||
throw new InvalidPathException('Invalid target path: Filename cannot be empty');
|
throw new InvalidPathException('Invalid target path: Filename cannot be empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
$sourceHandle = $this->getState()->open($this->buildUrl($source), 'r');
|
$sourceHandle = $this->getState()->open($this->buildUrl($source), 'r');
|
||||||
if (!$sourceHandle) {
|
|
||||||
throw new InvalidResourceException('Failed opening remote file "' . $source . '" for reading');
|
|
||||||
}
|
|
||||||
|
|
||||||
$targetHandle = @fopen($target, 'wb');
|
$targetHandle = @fopen($target, 'wb');
|
||||||
if (!$targetHandle) {
|
if (!$targetHandle) {
|
||||||
|
|
@ -242,7 +243,7 @@ class NativeShare extends AbstractShare {
|
||||||
throw new InvalidResourceException('Failed opening local file "' . $target . '" for writing: ' . $reason);
|
throw new InvalidResourceException('Failed opening local file "' . $target . '" for writing: ' . $reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($data = $this->getState()->read($sourceHandle, NativeReadStream::CHUNK_SIZE)) {
|
while ($data = $this->getState()->read($sourceHandle, NativeReadStream::CHUNK_SIZE, $source)) {
|
||||||
fwrite($targetHandle, $data);
|
fwrite($targetHandle, $data);
|
||||||
}
|
}
|
||||||
$this->getState()->close($sourceHandle, $this->buildUrl($source));
|
$this->getState()->close($sourceHandle, $this->buildUrl($source));
|
||||||
|
|
@ -255,10 +256,10 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $source
|
* @param string $source
|
||||||
* @return resource a read only stream with the contents of the remote file
|
* @return resource a read only stream with the contents of the remote file
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function read($source) {
|
public function read(string $source) {
|
||||||
$url = $this->buildUrl($source);
|
$url = $this->buildUrl($source);
|
||||||
$handle = $this->getState()->open($url, 'r');
|
$handle = $this->getState()->open($url, 'r');
|
||||||
return NativeReadStream::wrap($this->getState(), $handle, 'r', $url);
|
return NativeReadStream::wrap($this->getState(), $handle, 'r', $url);
|
||||||
|
|
@ -271,10 +272,10 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $source
|
* @param string $source
|
||||||
* @return resource a writeable stream
|
* @return resource a writeable stream
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function write($source) {
|
public function write(string $source) {
|
||||||
$url = $this->buildUrl($source);
|
$url = $this->buildUrl($source);
|
||||||
$handle = $this->getState()->create($url);
|
$handle = $this->getState()->create($url);
|
||||||
return NativeWriteStream::wrap($this->getState(), $handle, 'w', $url);
|
return NativeWriteStream::wrap($this->getState(), $handle, 'w', $url);
|
||||||
|
|
@ -286,10 +287,10 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $source
|
* @param string $source
|
||||||
* @return resource a writeable stream
|
* @return resource a writeable stream
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function append($source) {
|
public function append(string $source) {
|
||||||
$url = $this->buildUrl($source);
|
$url = $this->buildUrl($source);
|
||||||
$handle = $this->getState()->open($url, "a+");
|
$handle = $this->getState()->open($url, "a+");
|
||||||
return NativeWriteStream::wrap($this->getState(), $handle, "a", $url);
|
return NativeWriteStream::wrap($this->getState(), $handle, "a", $url);
|
||||||
|
|
@ -302,7 +303,7 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $attribute attribute to get the info
|
* @param string $attribute attribute to get the info
|
||||||
* @return string the attribute value
|
* @return string the attribute value
|
||||||
*/
|
*/
|
||||||
public function getAttribute($path, $attribute) {
|
public function getAttribute(string $path, string $attribute): string {
|
||||||
return $this->getState()->getxattr($this->buildUrl($path), $attribute);
|
return $this->getState()->getxattr($this->buildUrl($path), $attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -314,7 +315,7 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string|int $value
|
* @param string|int $value
|
||||||
* @return mixed the attribute value
|
* @return mixed the attribute value
|
||||||
*/
|
*/
|
||||||
public function setAttribute($path, $attribute, $value) {
|
public function setAttribute(string $path, string $attribute, $value) {
|
||||||
if ($attribute === 'system.dos_attr.mode' and is_int($value)) {
|
if ($attribute === 'system.dos_attr.mode' and is_int($value)) {
|
||||||
$value = '0x' . dechex($value);
|
$value = '0x' . dechex($value);
|
||||||
}
|
}
|
||||||
|
|
@ -329,7 +330,7 @@ class NativeShare extends AbstractShare {
|
||||||
* @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
|
* @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function setMode($path, $mode) {
|
public function setMode(string $path, int $mode) {
|
||||||
return $this->setAttribute($path, 'system.dos_attr.mode', $mode);
|
return $this->setAttribute($path, 'system.dos_attr.mode', $mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,7 +341,7 @@ class NativeShare extends AbstractShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return INotifyHandler
|
* @return INotifyHandler
|
||||||
*/
|
*/
|
||||||
public function notify($path) {
|
public function notify(string $path): INotifyHandler {
|
||||||
// php-smbclient does not 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
|
// so we use the smbclient based backend for this
|
||||||
if (!Server::available($this->server->getSystem())) {
|
if (!Server::available($this->server->getSystem())) {
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class NativeState {
|
||||||
113 => NoRouteToHostException::class
|
113 => NoRouteToHostException::class
|
||||||
];
|
];
|
||||||
|
|
||||||
protected function handleError($path) {
|
protected function handleError(?string $path) {
|
||||||
$error = smbclient_state_errno($this->state);
|
$error = smbclient_state_errno($this->state);
|
||||||
if ($error === 0) {
|
if ($error === 0) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -66,7 +66,7 @@ class NativeState {
|
||||||
throw Exception::fromMap(self::EXCEPTION_MAP, $error, $path);
|
throw Exception::fromMap(self::EXCEPTION_MAP, $error, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function testResult($result, $uri) {
|
protected function testResult($result, ?string $uri) {
|
||||||
if ($result === false or $result === null) {
|
if ($result === false or $result === null) {
|
||||||
// smb://host/share/path
|
// smb://host/share/path
|
||||||
if (is_string($uri) && count(explode('/', $uri, 5)) > 4) {
|
if (is_string($uri) && count(explode('/', $uri, 5)) > 4) {
|
||||||
|
|
@ -111,32 +111,24 @@ class NativeState {
|
||||||
* @param string $uri
|
* @param string $uri
|
||||||
* @return resource
|
* @return resource
|
||||||
*/
|
*/
|
||||||
public function opendir($uri) {
|
public function opendir(string $uri) {
|
||||||
$result = @smbclient_opendir($this->state, $uri);
|
$result = @smbclient_opendir($this->state, $uri);
|
||||||
|
|
||||||
$this->testResult($result, $uri);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function readdir($dir, string $path): array {
|
||||||
* @param resource $dir
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function readdir($dir) {
|
|
||||||
$result = @smbclient_readdir($this->state, $dir);
|
$result = @smbclient_readdir($this->state, $dir);
|
||||||
|
|
||||||
$this->testResult($result, $dir);
|
$this->testResult($result, $path);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function closedir($dir, string $path): bool {
|
||||||
* @param resource $dir
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function closedir($dir) {
|
|
||||||
$result = smbclient_closedir($this->state, $dir);
|
$result = smbclient_closedir($this->state, $dir);
|
||||||
|
|
||||||
$this->testResult($result, $dir);
|
$this->testResult($result, $path);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,7 +137,7 @@ class NativeState {
|
||||||
* @param string $new
|
* @param string $new
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function rename($old, $new) {
|
public function rename(string $old, string $new): bool {
|
||||||
$result = @smbclient_rename($this->state, $old, $this->state, $new);
|
$result = @smbclient_rename($this->state, $old, $this->state, $new);
|
||||||
|
|
||||||
$this->testResult($result, $new);
|
$this->testResult($result, $new);
|
||||||
|
|
@ -156,7 +148,7 @@ class NativeState {
|
||||||
* @param string $uri
|
* @param string $uri
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function unlink($uri) {
|
public function unlink(string $uri): bool {
|
||||||
$result = @smbclient_unlink($this->state, $uri);
|
$result = @smbclient_unlink($this->state, $uri);
|
||||||
|
|
||||||
$this->testResult($result, $uri);
|
$this->testResult($result, $uri);
|
||||||
|
|
@ -168,7 +160,7 @@ class NativeState {
|
||||||
* @param int $mask
|
* @param int $mask
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function mkdir($uri, $mask = 0777) {
|
public function mkdir(string $uri, int $mask = 0777): bool {
|
||||||
$result = @smbclient_mkdir($this->state, $uri, $mask);
|
$result = @smbclient_mkdir($this->state, $uri, $mask);
|
||||||
|
|
||||||
$this->testResult($result, $uri);
|
$this->testResult($result, $uri);
|
||||||
|
|
@ -179,7 +171,7 @@ class NativeState {
|
||||||
* @param string $uri
|
* @param string $uri
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function rmdir($uri) {
|
public function rmdir(string $uri): bool {
|
||||||
$result = @smbclient_rmdir($this->state, $uri);
|
$result = @smbclient_rmdir($this->state, $uri);
|
||||||
|
|
||||||
$this->testResult($result, $uri);
|
$this->testResult($result, $uri);
|
||||||
|
|
@ -190,21 +182,17 @@ class NativeState {
|
||||||
* @param string $uri
|
* @param string $uri
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function stat($uri) {
|
public function stat(string $uri): array {
|
||||||
$result = @smbclient_stat($this->state, $uri);
|
$result = @smbclient_stat($this->state, $uri);
|
||||||
|
|
||||||
$this->testResult($result, $uri);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function fstat($file, string $path): array {
|
||||||
* @param resource $file
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function fstat($file) {
|
|
||||||
$result = @smbclient_fstat($this->state, $file);
|
$result = @smbclient_fstat($this->state, $file);
|
||||||
|
|
||||||
$this->testResult($result, $file);
|
$this->testResult($result, $path);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,7 +202,7 @@ class NativeState {
|
||||||
* @param int $mask
|
* @param int $mask
|
||||||
* @return resource
|
* @return resource
|
||||||
*/
|
*/
|
||||||
public function open($uri, $mode, $mask = 0666) {
|
public function open(string $uri, string $mode, int $mask = 0666) {
|
||||||
$result = @smbclient_open($this->state, $uri, $mode, $mask);
|
$result = @smbclient_open($this->state, $uri, $mode, $mask);
|
||||||
|
|
||||||
$this->testResult($result, $uri);
|
$this->testResult($result, $uri);
|
||||||
|
|
@ -226,22 +214,17 @@ class NativeState {
|
||||||
* @param int $mask
|
* @param int $mask
|
||||||
* @return resource
|
* @return resource
|
||||||
*/
|
*/
|
||||||
public function create($uri, $mask = 0666) {
|
public function create(string $uri, int $mask = 0666) {
|
||||||
$result = @smbclient_creat($this->state, $uri, $mask);
|
$result = @smbclient_creat($this->state, $uri, $mask);
|
||||||
|
|
||||||
$this->testResult($result, $uri);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function read($file, int $bytes, string $path): string {
|
||||||
* @param resource $file
|
|
||||||
* @param int $bytes
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function read($file, $bytes) {
|
|
||||||
$result = @smbclient_read($this->state, $file, $bytes);
|
$result = @smbclient_read($this->state, $file, $bytes);
|
||||||
|
|
||||||
$this->testResult($result, $file);
|
$this->testResult($result, $path);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -249,10 +232,10 @@ class NativeState {
|
||||||
* @param resource $file
|
* @param resource $file
|
||||||
* @param string $data
|
* @param string $data
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param int $length
|
* @param int|null $length
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function write($file, $data, $path, $length = null) {
|
public function write($file, string $data, string $path, ?int $length = null): int {
|
||||||
$result = @smbclient_write($this->state, $file, $data, $length);
|
$result = @smbclient_write($this->state, $file, $data, $length);
|
||||||
|
|
||||||
$this->testResult($result, $path);
|
$this->testResult($result, $path);
|
||||||
|
|
@ -263,28 +246,24 @@ class NativeState {
|
||||||
* @param resource $file
|
* @param resource $file
|
||||||
* @param int $offset
|
* @param int $offset
|
||||||
* @param int $whence SEEK_SET | SEEK_CUR | SEEK_END
|
* @param int $whence SEEK_SET | SEEK_CUR | SEEK_END
|
||||||
|
* @param string|null $path
|
||||||
* @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) {
|
public function lseek($file, int $offset, int $whence = SEEK_SET, string $path = null) {
|
||||||
$result = @smbclient_lseek($this->state, $file, $offset, $whence);
|
$result = @smbclient_lseek($this->state, $file, $offset, $whence);
|
||||||
|
|
||||||
$this->testResult($result, $file);
|
$this->testResult($result, $path);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function ftruncate($file, int $size, string $path): bool {
|
||||||
* @param resource $file
|
|
||||||
* @param int $size
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function ftruncate($file, $size) {
|
|
||||||
$result = @smbclient_ftruncate($this->state, $file, $size);
|
$result = @smbclient_ftruncate($this->state, $file, $size);
|
||||||
|
|
||||||
$this->testResult($result, $file);
|
$this->testResult($result, $path);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close($file, $path) {
|
public function close($file, string $path) {
|
||||||
$result = @smbclient_close($this->state, $file);
|
$result = @smbclient_close($this->state, $file);
|
||||||
|
|
||||||
$this->testResult($result, $path);
|
$this->testResult($result, $path);
|
||||||
|
|
@ -296,7 +275,7 @@ class NativeState {
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getxattr($uri, $key) {
|
public function getxattr(string $uri, string $key) {
|
||||||
$result = @smbclient_getxattr($this->state, $uri, $key);
|
$result = @smbclient_getxattr($this->state, $uri, $key);
|
||||||
|
|
||||||
$this->testResult($result, $uri);
|
$this->testResult($result, $uri);
|
||||||
|
|
@ -310,7 +289,7 @@ class NativeState {
|
||||||
* @param int $flags
|
* @param int $flags
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function setxattr($uri, $key, $value, $flags = 0) {
|
public function setxattr(string $uri, string $key, string $value, int $flags = 0) {
|
||||||
$result = @smbclient_setxattr($this->state, $uri, $key, $value, $flags);
|
$result = @smbclient_setxattr($this->state, $uri, $key, $value, $flags);
|
||||||
|
|
||||||
$this->testResult($result, $uri);
|
$this->testResult($result, $uri);
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ class NativeStream implements File {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_read($count) {
|
public function stream_read($count) {
|
||||||
$result = $this->state->read($this->handle, $count);
|
$result = $this->state->read($this->handle, $count, $this->url);
|
||||||
if (strlen($result) < $count) {
|
if (strlen($result) < $count) {
|
||||||
$this->eof = true;
|
$this->eof = true;
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +96,7 @@ class NativeStream implements File {
|
||||||
public function stream_seek($offset, $whence = SEEK_SET) {
|
public function stream_seek($offset, $whence = SEEK_SET) {
|
||||||
$this->eof = false;
|
$this->eof = false;
|
||||||
try {
|
try {
|
||||||
return $this->state->lseek($this->handle, $offset, $whence) !== false;
|
return $this->state->lseek($this->handle, $offset, $whence, $this->url) !== false;
|
||||||
} catch (InvalidRequestException $e) {
|
} catch (InvalidRequestException $e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +111,7 @@ class NativeStream implements File {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_tell() {
|
public function stream_tell() {
|
||||||
return $this->state->lseek($this->handle, 0, SEEK_CUR);
|
return $this->state->lseek($this->handle, 0, SEEK_CUR, $this->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_write($data) {
|
public function stream_write($data) {
|
||||||
|
|
@ -119,7 +119,7 @@ class NativeStream implements File {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_truncate($size) {
|
public function stream_truncate($size) {
|
||||||
return $this->state->ftruncate($this->handle, $size);
|
return $this->state->ftruncate($this->handle, $size, $this->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2) {
|
public function stream_set_option($option, $arg1, $arg2) {
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ class ServerFactory {
|
||||||
* @return IServer
|
* @return IServer
|
||||||
* @throws DependencyException
|
* @throws DependencyException
|
||||||
*/
|
*/
|
||||||
public function createServer(string $host, IAuth $credentials) {
|
public function createServer(string $host, IAuth $credentials): IServer {
|
||||||
foreach (self::BACKENDS as $backend) {
|
foreach (self::BACKENDS as $backend) {
|
||||||
if (call_user_func("$backend::available", $this->system)) {
|
if (call_user_func("$backend::available", $this->system)) {
|
||||||
return new $backend($host, $credentials, $this->system, $this->timeZoneProvider, $this->options);
|
return new $backend($host, $credentials, $this->system, $this->timeZoneProvider, $this->options);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class StringBuffer {
|
||||||
$this->pos = 0;
|
$this->pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function push(string $data) {
|
public function push(string $data): int {
|
||||||
$this->buffer = $this->flush() . $data;
|
$this->buffer = $this->flush() . $data;
|
||||||
return strlen($data);
|
return strlen($data);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Icewind\SMB;
|
||||||
use Icewind\SMB\Exception\Exception;
|
use Icewind\SMB\Exception\Exception;
|
||||||
|
|
||||||
class System implements ISystem {
|
class System implements ISystem {
|
||||||
/** @var (string|bool)[] */
|
/** @var (string|null)[] */
|
||||||
private $paths = [];
|
private $paths = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -20,7 +20,7 @@ class System implements ISystem {
|
||||||
* @return string
|
* @return string
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getFD($num) {
|
public function getFD(int $num): string {
|
||||||
$folders = [
|
$folders = [
|
||||||
'/proc/self/fd',
|
'/proc/self/fd',
|
||||||
'/dev/fd'
|
'/dev/fd'
|
||||||
|
|
@ -33,36 +33,36 @@ class System implements ISystem {
|
||||||
throw new Exception('Cant find file descriptor path');
|
throw new Exception('Cant find file descriptor path');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSmbclientPath() {
|
public function getSmbclientPath(): ?string {
|
||||||
return $this->getBinaryPath('smbclient');
|
return $this->getBinaryPath('smbclient');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNetPath() {
|
public function getNetPath(): ?string {
|
||||||
return $this->getBinaryPath('net');
|
return $this->getBinaryPath('net');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSmbcAclsPath() {
|
public function getSmbcAclsPath(): ?string {
|
||||||
return $this->getBinaryPath('smbcacls');
|
return $this->getBinaryPath('smbcacls');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStdBufPath() {
|
public function getStdBufPath(): ?string {
|
||||||
return $this->getBinaryPath('stdbuf');
|
return $this->getBinaryPath('stdbuf');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDatePath() {
|
public function getDatePath(): ?string {
|
||||||
return $this->getBinaryPath('date');
|
return $this->getBinaryPath('date');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function libSmbclientAvailable() {
|
public function libSmbclientAvailable(): bool {
|
||||||
return function_exists('smbclient_state_new');
|
return function_exists('smbclient_state_new');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getBinaryPath($binary) {
|
protected function getBinaryPath($binary): ?string {
|
||||||
if (!isset($this->paths[$binary])) {
|
if (!isset($this->paths[$binary])) {
|
||||||
$result = null;
|
$result = null;
|
||||||
$output = [];
|
$output = [];
|
||||||
exec("which $binary 2>&1", $output, $result);
|
exec("which $binary 2>&1", $output, $result);
|
||||||
$this->paths[$binary] = $result === 0 ? trim(implode('', $output)) : false;
|
$this->paths[$binary] = $result === 0 ? trim(implode('', $output)) : null;
|
||||||
}
|
}
|
||||||
return $this->paths[$binary];
|
return $this->paths[$binary];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class TimeZoneProvider implements ITimeZoneProvider {
|
||||||
$this->system = $system;
|
$this->system = $system;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get($host) {
|
public function get(string $host): string {
|
||||||
if (!isset($this->timeZones[$host])) {
|
if (!isset($this->timeZones[$host])) {
|
||||||
$timeZone = null;
|
$timeZone = null;
|
||||||
$net = $this->system->getNetPath();
|
$net = $this->system->getNetPath();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
namespace Icewind\SMB\Wrapped;
|
namespace Icewind\SMB\Wrapped;
|
||||||
|
|
||||||
|
use Icewind\SMB\Exception\AccessDeniedException;
|
||||||
use Icewind\SMB\Exception\AuthenticationException;
|
use Icewind\SMB\Exception\AuthenticationException;
|
||||||
use Icewind\SMB\Exception\ConnectException;
|
use Icewind\SMB\Exception\ConnectException;
|
||||||
use Icewind\SMB\Exception\ConnectionException;
|
use Icewind\SMB\Exception\ConnectionException;
|
||||||
|
|
@ -31,7 +32,7 @@ class Connection extends RawConnection {
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
*/
|
*/
|
||||||
public function write($input) {
|
public function write(string $input) {
|
||||||
return parent::write($input . PHP_EOL);
|
return parent::write($input . PHP_EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,15 +57,16 @@ class Connection extends RawConnection {
|
||||||
/**
|
/**
|
||||||
* get all unprocessed output from smbclient until the next prompt
|
* get all unprocessed output from smbclient until the next prompt
|
||||||
*
|
*
|
||||||
* @param callable $callback (optional) callback to call for every line read
|
* @param callable|null $callback (optional) callback to call for every line read
|
||||||
* @return string[]
|
* @return string[]
|
||||||
* @throws AuthenticationException
|
* @throws AuthenticationException
|
||||||
* @throws ConnectException
|
* @throws ConnectException
|
||||||
* @throws ConnectionException
|
* @throws ConnectionException
|
||||||
* @throws InvalidHostException
|
* @throws InvalidHostException
|
||||||
* @throws NoLoginServerException
|
* @throws NoLoginServerException
|
||||||
|
* @throws AccessDeniedException
|
||||||
*/
|
*/
|
||||||
public function read(callable $callback = null) {
|
public function read(callable $callback = null): array {
|
||||||
if (!$this->isValid()) {
|
if (!$this->isValid()) {
|
||||||
throw new ConnectionException('Connection not valid');
|
throw new ConnectionException('Connection not valid');
|
||||||
}
|
}
|
||||||
|
|
@ -98,13 +100,7 @@ class Connection extends RawConnection {
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function isPrompt(string $line): bool {
|
||||||
* Check
|
|
||||||
*
|
|
||||||
* @param string $line
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function isPrompt(string $line) {
|
|
||||||
return mb_substr($line, 0, self::DELIMITER_LENGTH) === self::DELIMITER;
|
return mb_substr($line, 0, self::DELIMITER_LENGTH) === self::DELIMITER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,7 +121,7 @@ class Connection extends RawConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close($terminate = true) {
|
public function close(bool $terminate = true) {
|
||||||
if (get_resource_type($this->getInputStream()) === 'stream') {
|
if (get_resource_type($this->getInputStream()) === 'stream') {
|
||||||
// ignore any errors while trying to send the close command, the process might already be dead
|
// ignore any errors while trying to send the close command, the process might already be dead
|
||||||
@$this->write('close' . PHP_EOL);
|
@$this->write('close' . PHP_EOL);
|
||||||
|
|
|
||||||
|
|
@ -11,45 +11,20 @@ use Icewind\SMB\ACL;
|
||||||
use Icewind\SMB\IFileInfo;
|
use Icewind\SMB\IFileInfo;
|
||||||
|
|
||||||
class FileInfo implements IFileInfo {
|
class FileInfo implements IFileInfo {
|
||||||
/**
|
/** @var string */
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $path;
|
protected $path;
|
||||||
|
/** @var string */
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $name;
|
protected $name;
|
||||||
|
/** @var int */
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
protected $size;
|
protected $size;
|
||||||
|
/** @var int */
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
protected $time;
|
protected $time;
|
||||||
|
/** @var int */
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
protected $mode;
|
protected $mode;
|
||||||
|
/** @var callable */
|
||||||
/**
|
|
||||||
* @var callable
|
|
||||||
*/
|
|
||||||
protected $aclCallback;
|
protected $aclCallback;
|
||||||
|
|
||||||
/**
|
public function __construct(string $path, string $name, int $size, int $time, int $mode, callable $aclCallback) {
|
||||||
* @param string $path
|
|
||||||
* @param string $name
|
|
||||||
* @param int $size
|
|
||||||
* @param int $time
|
|
||||||
* @param int $mode
|
|
||||||
* @param callable $aclCallback
|
|
||||||
*/
|
|
||||||
public function __construct($path, $name, $size, $time, $mode, callable $aclCallback) {
|
|
||||||
$this->path = $path;
|
$this->path = $path;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->size = $size;
|
$this->size = $size;
|
||||||
|
|
@ -61,63 +36,39 @@ class FileInfo implements IFileInfo {
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getPath() {
|
public function getPath(): string {
|
||||||
return $this->path;
|
return $this->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getName(): string {
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getName() {
|
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getSize(): int {
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getSize() {
|
|
||||||
return $this->size;
|
return $this->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function getMTime(): int {
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getMTime() {
|
|
||||||
return $this->time;
|
return $this->time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isDirectory(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isDirectory() {
|
|
||||||
return (bool)($this->mode & IFileInfo::MODE_DIRECTORY);
|
return (bool)($this->mode & IFileInfo::MODE_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isReadOnly(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isReadOnly() {
|
|
||||||
return (bool)($this->mode & IFileInfo::MODE_READONLY);
|
return (bool)($this->mode & IFileInfo::MODE_READONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isHidden(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isHidden() {
|
|
||||||
return (bool)($this->mode & IFileInfo::MODE_HIDDEN);
|
return (bool)($this->mode & IFileInfo::MODE_HIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isSystem(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isSystem() {
|
|
||||||
return (bool)($this->mode & IFileInfo::MODE_SYSTEM);
|
return (bool)($this->mode & IFileInfo::MODE_SYSTEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isArchived(): bool {
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isArchived() {
|
|
||||||
return (bool)($this->mode & IFileInfo::MODE_ARCHIVE);
|
return (bool)($this->mode & IFileInfo::MODE_ARCHIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class NotifyHandler implements INotifyHandler {
|
||||||
* @param Connection $connection
|
* @param Connection $connection
|
||||||
* @param string $path
|
* @param string $path
|
||||||
*/
|
*/
|
||||||
public function __construct(Connection $connection, $path) {
|
public function __construct(Connection $connection, string $path) {
|
||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
$this->path = $path;
|
$this->path = $path;
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +45,7 @@ class NotifyHandler implements INotifyHandler {
|
||||||
*
|
*
|
||||||
* @return Change[]
|
* @return Change[]
|
||||||
*/
|
*/
|
||||||
public function getChanges() {
|
public function getChanges(): array {
|
||||||
if (!$this->listening) {
|
if (!$this->listening) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +66,7 @@ class NotifyHandler implements INotifyHandler {
|
||||||
*
|
*
|
||||||
* @param callable $callback
|
* @param callable $callback
|
||||||
*/
|
*/
|
||||||
public function listen($callback) {
|
public function listen(callable $callback): void {
|
||||||
if ($this->listening) {
|
if ($this->listening) {
|
||||||
$this->connection->read(function ($line) use ($callback) {
|
$this->connection->read(function ($line) use ($callback) {
|
||||||
$this->checkForError($line);
|
$this->checkForError($line);
|
||||||
|
|
@ -78,7 +78,7 @@ class NotifyHandler implements INotifyHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function parseChangeLine($line) {
|
private function parseChangeLine(string $line): ?Change {
|
||||||
$code = (int)substr($line, 0, 4);
|
$code = (int)substr($line, 0, 4);
|
||||||
if ($code === 0) {
|
if ($code === 0) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -91,7 +91,7 @@ class NotifyHandler implements INotifyHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkForError($line) {
|
private function checkForError(string $line) {
|
||||||
if (substr($line, 0, 16) === 'notify returned ') {
|
if (substr($line, 0, 16) === 'notify returned ') {
|
||||||
$error = substr($line, 16);
|
$error = substr($line, 16);
|
||||||
throw Exception::fromMap(array_merge(self::EXCEPTION_MAP, Parser::EXCEPTION_MAP), $error, 'Notify is not supported with the used smb version');
|
throw Exception::fromMap(array_merge(self::EXCEPTION_MAP, Parser::EXCEPTION_MAP), $error, 'Notify is not supported with the used smb version');
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,6 @@ class Parser {
|
||||||
*/
|
*/
|
||||||
protected $timeZone;
|
protected $timeZone;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $host;
|
|
||||||
|
|
||||||
// see error.h
|
// see error.h
|
||||||
const EXCEPTION_MAP = [
|
const EXCEPTION_MAP = [
|
||||||
ErrorCodes::LogonFailure => AuthenticationException::class,
|
ErrorCodes::LogonFailure => AuthenticationException::class,
|
||||||
|
|
@ -65,17 +60,17 @@ class Parser {
|
||||||
$this->timeZone = $timeZone;
|
$this->timeZone = $timeZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getErrorCode($line) {
|
private function getErrorCode(string $line): ?string {
|
||||||
$parts = explode(' ', $line);
|
$parts = explode(' ', $line);
|
||||||
foreach ($parts as $part) {
|
foreach ($parts as $part) {
|
||||||
if (substr($part, 0, 9) === 'NT_STATUS') {
|
if (substr($part, 0, 9) === 'NT_STATUS') {
|
||||||
return $part;
|
return $part;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkForError($output, $path) {
|
public function checkForError(array $output, string $path): void {
|
||||||
if (strpos($output[0], 'does not exist')) {
|
if (strpos($output[0], 'does not exist')) {
|
||||||
throw new NotFoundException($path);
|
throw new NotFoundException($path);
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +93,7 @@ class Parser {
|
||||||
* @throws NoLoginServerException
|
* @throws NoLoginServerException
|
||||||
* @throws AccessDeniedException
|
* @throws AccessDeniedException
|
||||||
*/
|
*/
|
||||||
public function checkConnectionError(string $line) {
|
public function checkConnectionError(string $line): void {
|
||||||
$line = rtrim($line, ')');
|
$line = rtrim($line, ')');
|
||||||
if (substr($line, -23) === ErrorCodes::LogonFailure) {
|
if (substr($line, -23) === ErrorCodes::LogonFailure) {
|
||||||
throw new AuthenticationException('Invalid login');
|
throw new AuthenticationException('Invalid login');
|
||||||
|
|
@ -120,7 +115,7 @@ class Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseMode($mode) {
|
public function parseMode(string $mode): int {
|
||||||
$result = 0;
|
$result = 0;
|
||||||
foreach (self::MODE_STRINGS as $char => $val) {
|
foreach (self::MODE_STRINGS as $char => $val) {
|
||||||
if (strpos($mode, $char) !== false) {
|
if (strpos($mode, $char) !== false) {
|
||||||
|
|
@ -130,7 +125,7 @@ class Parser {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseStat($output) {
|
public function parseStat(array $output): array {
|
||||||
$data = [];
|
$data = [];
|
||||||
foreach ($output as $line) {
|
foreach ($output as $line) {
|
||||||
// A line = explode statement may not fill all array elements
|
// A line = explode statement may not fill all array elements
|
||||||
|
|
@ -151,7 +146,13 @@ class Parser {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseDir($output, $basePath, callable $aclCallback) {
|
/**
|
||||||
|
* @param array $output
|
||||||
|
* @param string $basePath
|
||||||
|
* @param callable $aclCallback
|
||||||
|
* @return FileInfo[]
|
||||||
|
*/
|
||||||
|
public function parseDir(array $output, string $basePath, callable $aclCallback): array {
|
||||||
//last line is used space
|
//last line is used space
|
||||||
array_pop($output);
|
array_pop($output);
|
||||||
$regex = '/^\s*(.*?)\s\s\s\s+(?:([NDHARS]*)\s+)?([0-9]+)\s+(.*)$/';
|
$regex = '/^\s*(.*?)\s\s\s\s+(?:([NDHARS]*)\s+)?([0-9]+)\s+(.*)$/';
|
||||||
|
|
@ -173,7 +174,11 @@ class Parser {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseListShares($output) {
|
/**
|
||||||
|
* @param array $output
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function parseListShares(array $output): array {
|
||||||
$shareNames = [];
|
$shareNames = [];
|
||||||
foreach ($output as $line) {
|
foreach ($output as $line) {
|
||||||
if (strpos($line, '|')) {
|
if (strpos($line, '|')) {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ namespace Icewind\SMB\Wrapped;
|
||||||
|
|
||||||
use Icewind\SMB\Exception\ConnectException;
|
use Icewind\SMB\Exception\ConnectException;
|
||||||
use Icewind\SMB\Exception\ConnectionException;
|
use Icewind\SMB\Exception\ConnectionException;
|
||||||
use Icewind\SMB\Exception\ConnectionResetException;
|
|
||||||
|
|
||||||
class RawConnection {
|
class RawConnection {
|
||||||
/**
|
/**
|
||||||
|
|
@ -43,9 +42,7 @@ class RawConnection {
|
||||||
*/
|
*/
|
||||||
private $authStream = null;
|
private $authStream = null;
|
||||||
|
|
||||||
private $connected = false;
|
public function __construct(string $command, array $env = []) {
|
||||||
|
|
||||||
public function __construct($command, array $env = []) {
|
|
||||||
$this->command = $command;
|
$this->command = $command;
|
||||||
$this->env = $env;
|
$this->env = $env;
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +75,6 @@ class RawConnection {
|
||||||
if (!$this->isValid()) {
|
if (!$this->isValid()) {
|
||||||
throw new ConnectionException();
|
throw new ConnectionException();
|
||||||
}
|
}
|
||||||
$this->connected = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -86,7 +82,7 @@ class RawConnection {
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isValid() {
|
public function isValid(): bool {
|
||||||
if (is_resource($this->process)) {
|
if (is_resource($this->process)) {
|
||||||
$status = proc_get_status($this->process);
|
$status = proc_get_status($this->process);
|
||||||
return $status['running'];
|
return $status['running'];
|
||||||
|
|
@ -99,8 +95,9 @@ class RawConnection {
|
||||||
* send input to the process
|
* send input to the process
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
|
* @return int|bool
|
||||||
*/
|
*/
|
||||||
public function write($input) {
|
public function write(string $input) {
|
||||||
$result = @fwrite($this->getInputStream(), $input);
|
$result = @fwrite($this->getInputStream(), $input);
|
||||||
fflush($this->getInputStream());
|
fflush($this->getInputStream());
|
||||||
return $result;
|
return $result;
|
||||||
|
|
@ -118,7 +115,7 @@ class RawConnection {
|
||||||
/**
|
/**
|
||||||
* read a line of output
|
* read a line of output
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string|false
|
||||||
*/
|
*/
|
||||||
public function readError() {
|
public function readError() {
|
||||||
return trim(stream_get_line($this->getErrorStream(), 4086));
|
return trim(stream_get_line($this->getErrorStream(), 4086));
|
||||||
|
|
@ -127,9 +124,9 @@ class RawConnection {
|
||||||
/**
|
/**
|
||||||
* get all output until the process closes
|
* get all output until the process closes
|
||||||
*
|
*
|
||||||
* @return array
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function readAll() {
|
public function readAll(): array {
|
||||||
$output = [];
|
$output = [];
|
||||||
while ($line = $this->readLine()) {
|
while ($line = $this->readLine()) {
|
||||||
$output[] = $line;
|
$output[] = $line;
|
||||||
|
|
@ -161,8 +158,8 @@ class RawConnection {
|
||||||
return $this->pipes[5];
|
return $this->pipes[5];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function writeAuthentication($user, $password) {
|
public function writeAuthentication(?string $user, ?string $password) {
|
||||||
$auth = ($password === false)
|
$auth = ($password === null)
|
||||||
? "username=$user"
|
? "username=$user"
|
||||||
: "username=$user\npassword=$password\n";
|
: "username=$user\npassword=$password\n";
|
||||||
|
|
||||||
|
|
@ -170,7 +167,7 @@ class RawConnection {
|
||||||
fwrite($this->getAuthStream(), $auth);
|
fwrite($this->getAuthStream(), $auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close($terminate = true) {
|
public function close(bool $terminate = true) {
|
||||||
if (!is_resource($this->process)) {
|
if (!is_resource($this->process)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ class Server extends AbstractServer {
|
||||||
* @param ISystem $system
|
* @param ISystem $system
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function available(ISystem $system) {
|
public static function available(ISystem $system): bool {
|
||||||
return $system->getSmbclientPath();
|
return $system->getSmbclientPath() !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getAuthFileArgument() {
|
private function getAuthFileArgument(): string {
|
||||||
if ($this->getAuth()->getUsername()) {
|
if ($this->getAuth()->getUsername()) {
|
||||||
return '--authentication-file=' . $this->system->getFD(3);
|
return '--authentication-file=' . $this->system->getFD(3);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -42,7 +42,7 @@ class Server extends AbstractServer {
|
||||||
* @throws InvalidHostException
|
* @throws InvalidHostException
|
||||||
* @throws ConnectException
|
* @throws ConnectException
|
||||||
*/
|
*/
|
||||||
public function listShares() {
|
public function listShares(): array {
|
||||||
$maxProtocol = $this->options->getMaxProtocol();
|
$maxProtocol = $this->options->getMaxProtocol();
|
||||||
$minProtocol = $this->options->getMinProtocol();
|
$minProtocol = $this->options->getMinProtocol();
|
||||||
$command = sprintf(
|
$command = sprintf(
|
||||||
|
|
@ -93,7 +93,7 @@ class Server extends AbstractServer {
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @return IShare
|
* @return IShare
|
||||||
*/
|
*/
|
||||||
public function getShare($name) {
|
public function getShare(string $name): IShare {
|
||||||
return new Share($this, $name, $this->system);
|
return new Share($this, $name, $this->system);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,12 @@ namespace Icewind\SMB\Wrapped;
|
||||||
|
|
||||||
use Icewind\SMB\AbstractShare;
|
use Icewind\SMB\AbstractShare;
|
||||||
use Icewind\SMB\ACL;
|
use Icewind\SMB\ACL;
|
||||||
|
use Icewind\SMB\Exception\AlreadyExistsException;
|
||||||
|
use Icewind\SMB\Exception\AuthenticationException;
|
||||||
use Icewind\SMB\Exception\ConnectionException;
|
use Icewind\SMB\Exception\ConnectionException;
|
||||||
use Icewind\SMB\Exception\DependencyException;
|
use Icewind\SMB\Exception\DependencyException;
|
||||||
use Icewind\SMB\Exception\FileInUseException;
|
use Icewind\SMB\Exception\FileInUseException;
|
||||||
|
use Icewind\SMB\Exception\InvalidHostException;
|
||||||
use Icewind\SMB\Exception\InvalidTypeException;
|
use Icewind\SMB\Exception\InvalidTypeException;
|
||||||
use Icewind\SMB\Exception\NotFoundException;
|
use Icewind\SMB\Exception\NotFoundException;
|
||||||
use Icewind\SMB\Exception\InvalidRequestException;
|
use Icewind\SMB\Exception\InvalidRequestException;
|
||||||
|
|
@ -63,7 +66,7 @@ class Share extends AbstractShare {
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param ISystem $system
|
* @param ISystem $system
|
||||||
*/
|
*/
|
||||||
public function __construct(IServer $server, $name, ISystem $system) {
|
public function __construct(IServer $server, string $name, ISystem $system) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->server = $server;
|
$this->server = $server;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
|
@ -71,7 +74,7 @@ class Share extends AbstractShare {
|
||||||
$this->parser = new Parser($server->getTimeZone());
|
$this->parser = new Parser($server->getTimeZone());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getAuthFileArgument() {
|
private function getAuthFileArgument(): string {
|
||||||
if ($this->server->getAuth()->getUsername()) {
|
if ($this->server->getAuth()->getUsername()) {
|
||||||
return '--authentication-file=' . $this->system->getFD(3);
|
return '--authentication-file=' . $this->system->getFD(3);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -79,7 +82,7 @@ class Share extends AbstractShare {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getConnection() {
|
protected function getConnection(): Connection {
|
||||||
$maxProtocol = $this->server->getOptions()->getMaxProtocol();
|
$maxProtocol = $this->server->getOptions()->getMaxProtocol();
|
||||||
$minProtocol = $this->server->getOptions()->getMinProtocol();
|
$minProtocol = $this->server->getOptions()->getMinProtocol();
|
||||||
$command = sprintf(
|
$command = sprintf(
|
||||||
|
|
@ -106,9 +109,9 @@ class Share extends AbstractShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \Icewind\SMB\Exception\ConnectionException
|
* @throws ConnectionException
|
||||||
* @throws \Icewind\SMB\Exception\AuthenticationException
|
* @throws AuthenticationException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidHostException
|
* @throws InvalidHostException
|
||||||
*/
|
*/
|
||||||
protected function connect() {
|
protected function connect() {
|
||||||
if ($this->connection and $this->connection->isValid()) {
|
if ($this->connection and $this->connection->isValid()) {
|
||||||
|
|
@ -129,11 +132,11 @@ class Share extends AbstractShare {
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getName() {
|
public function getName(): string {
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function simpleCommand($command, $path) {
|
protected function simpleCommand(string $command, string $path): bool {
|
||||||
$escapedPath = $this->escapePath($path);
|
$escapedPath = $this->escapePath($path);
|
||||||
$cmd = $command . ' ' . $escapedPath;
|
$cmd = $command . ' ' . $escapedPath;
|
||||||
$output = $this->execute($cmd);
|
$output = $this->execute($cmd);
|
||||||
|
|
@ -144,12 +147,12 @@ class Share extends AbstractShare {
|
||||||
* List the content of a remote folder
|
* List the content of a remote folder
|
||||||
*
|
*
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return \Icewind\SMB\IFileInfo[]
|
* @return IFileInfo[]
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function dir($path) {
|
public function dir(string $path): array {
|
||||||
$escapedPath = $this->escapePath($path);
|
$escapedPath = $this->escapePath($path);
|
||||||
$output = $this->execute('cd ' . $escapedPath);
|
$output = $this->execute('cd ' . $escapedPath);
|
||||||
//check output for errors
|
//check output for errors
|
||||||
|
|
@ -165,9 +168,9 @@ class Share extends AbstractShare {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return \Icewind\SMB\IFileInfo
|
* @return IFileInfo
|
||||||
*/
|
*/
|
||||||
public function stat($path) {
|
public function stat(string $path): IFileInfo {
|
||||||
// some windows server setups don't seem to like the allinfo command
|
// some windows server setups don't seem to like the allinfo command
|
||||||
// use the dir command instead to get the file info where possible
|
// use the dir command instead to get the file info where possible
|
||||||
if ($path !== "" && $path !== "/") {
|
if ($path !== "" && $path !== "/") {
|
||||||
|
|
@ -204,10 +207,10 @@ class Share extends AbstractShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\AlreadyExistsException
|
* @throws AlreadyExistsException
|
||||||
*/
|
*/
|
||||||
public function mkdir($path) {
|
public function mkdir(string $path): bool {
|
||||||
return $this->simpleCommand('mkdir', $path);
|
return $this->simpleCommand('mkdir', $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,10 +220,10 @@ class Share extends AbstractShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function rmdir($path) {
|
public function rmdir(string $path): bool {
|
||||||
return $this->simpleCommand('rmdir', $path);
|
return $this->simpleCommand('rmdir', $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,7 +237,7 @@ class Share extends AbstractShare {
|
||||||
* @throws NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function del($path, $secondTry = false) {
|
public function del(string $path, bool $secondTry = false): bool {
|
||||||
//del return a file not found error when trying to delete a folder
|
//del return a file not found error when trying to delete a folder
|
||||||
//we catch it so we can check if $path doesn't exist or is of invalid type
|
//we catch it so we can check if $path doesn't exist or is of invalid type
|
||||||
try {
|
try {
|
||||||
|
|
@ -265,10 +268,10 @@ class Share extends AbstractShare {
|
||||||
* @param string $to
|
* @param string $to
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\AlreadyExistsException
|
* @throws AlreadyExistsException
|
||||||
*/
|
*/
|
||||||
public function rename($from, $to) {
|
public function rename(string $from, string $to): bool {
|
||||||
$path1 = $this->escapePath($from);
|
$path1 = $this->escapePath($from);
|
||||||
$path2 = $this->escapePath($to);
|
$path2 = $this->escapePath($to);
|
||||||
$output = $this->execute('rename ' . $path1 . ' ' . $path2);
|
$output = $this->execute('rename ' . $path1 . ' ' . $path2);
|
||||||
|
|
@ -282,10 +285,10 @@ class Share extends AbstractShare {
|
||||||
* @param string $target remove file
|
* @param string $target remove file
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function put($source, $target) {
|
public function put(string $source, string $target): bool {
|
||||||
$path1 = $this->escapeLocalPath($source); //first path is local, needs different escaping
|
$path1 = $this->escapeLocalPath($source); //first path is local, needs different escaping
|
||||||
$path2 = $this->escapePath($target);
|
$path2 = $this->escapePath($target);
|
||||||
$output = $this->execute('put ' . $path1 . ' ' . $path2);
|
$output = $this->execute('put ' . $path1 . ' ' . $path2);
|
||||||
|
|
@ -299,10 +302,10 @@ class Share extends AbstractShare {
|
||||||
* @param string $target local file
|
* @param string $target local file
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function get($source, $target) {
|
public function get(string $source, string $target): bool {
|
||||||
$path1 = $this->escapePath($source);
|
$path1 = $this->escapePath($source);
|
||||||
$path2 = $this->escapeLocalPath($target); //second path is local, needs different escaping
|
$path2 = $this->escapeLocalPath($target); //second path is local, needs different escaping
|
||||||
$output = $this->execute('get ' . $path1 . ' ' . $path2);
|
$output = $this->execute('get ' . $path1 . ' ' . $path2);
|
||||||
|
|
@ -315,10 +318,10 @@ class Share extends AbstractShare {
|
||||||
* @param string $source
|
* @param string $source
|
||||||
* @return resource a read only stream with the contents of the remote file
|
* @return resource a read only stream with the contents of the remote file
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function read($source) {
|
public function read(string $source) {
|
||||||
$source = $this->escapePath($source);
|
$source = $this->escapePath($source);
|
||||||
// since returned stream is closed by the caller we need to create a new instance
|
// 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
|
// since we can't re-use the same file descriptor over multiple calls
|
||||||
|
|
@ -337,10 +340,10 @@ class Share extends AbstractShare {
|
||||||
* @param string $target
|
* @param string $target
|
||||||
* @return resource a write only stream to upload a remote file
|
* @return resource a write only stream to upload a remote file
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
*/
|
*/
|
||||||
public function write($target) {
|
public function write(string $target) {
|
||||||
$target = $this->escapePath($target);
|
$target = $this->escapePath($target);
|
||||||
// since returned stream is closed by the caller we need to create a new instance
|
// 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
|
// since we can't re-use the same file descriptor over multiple calls
|
||||||
|
|
@ -363,9 +366,9 @@ class Share extends AbstractShare {
|
||||||
*
|
*
|
||||||
* @param string $target
|
* @param string $target
|
||||||
*
|
*
|
||||||
* @throws \Icewind\SMB\Exception\DependencyException
|
* @throws DependencyException
|
||||||
*/
|
*/
|
||||||
public function append($target) {
|
public function append(string $target) {
|
||||||
throw new DependencyException('php-libsmbclient is required for append');
|
throw new DependencyException('php-libsmbclient is required for append');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -374,7 +377,7 @@ class Share extends AbstractShare {
|
||||||
* @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
|
* @param int $mode a combination of FileInfo::MODE_READONLY, FileInfo::MODE_ARCHIVE, FileInfo::MODE_SYSTEM and FileInfo::MODE_HIDDEN, FileInfo::NORMAL
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function setMode($path, $mode) {
|
public function setMode(string $path, int $mode) {
|
||||||
$modeString = '';
|
$modeString = '';
|
||||||
foreach (self::MODE_MAP as $modeByte => $string) {
|
foreach (self::MODE_MAP as $modeByte => $string) {
|
||||||
if ($mode & $modeByte) {
|
if ($mode & $modeByte) {
|
||||||
|
|
@ -404,7 +407,7 @@ class Share extends AbstractShare {
|
||||||
* @throws ConnectionException
|
* @throws ConnectionException
|
||||||
* @throws DependencyException
|
* @throws DependencyException
|
||||||
*/
|
*/
|
||||||
public function notify($path) {
|
public function notify(string $path): INotifyHandler {
|
||||||
if (!$this->system->getStdBufPath()) { //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');
|
throw new DependencyException('stdbuf is required for usage of the notify command');
|
||||||
}
|
}
|
||||||
|
|
@ -418,7 +421,7 @@ class Share extends AbstractShare {
|
||||||
* @param string $command
|
* @param string $command
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function execute($command) {
|
protected function execute(string $command): array {
|
||||||
$this->connect();
|
$this->connect();
|
||||||
$this->connection->write($command . PHP_EOL);
|
$this->connection->write($command . PHP_EOL);
|
||||||
return $this->connection->read();
|
return $this->connection->read();
|
||||||
|
|
@ -431,14 +434,14 @@ class Share extends AbstractShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws \Icewind\SMB\Exception\AlreadyExistsException
|
* @throws AlreadyExistsException
|
||||||
* @throws \Icewind\SMB\Exception\AccessDeniedException
|
* @throws \Icewind\SMB\Exception\AccessDeniedException
|
||||||
* @throws \Icewind\SMB\Exception\NotEmptyException
|
* @throws \Icewind\SMB\Exception\NotEmptyException
|
||||||
* @throws \Icewind\SMB\Exception\InvalidTypeException
|
* @throws InvalidTypeException
|
||||||
* @throws \Icewind\SMB\Exception\Exception
|
* @throws \Icewind\SMB\Exception\Exception
|
||||||
* @throws NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
protected function parseOutput($lines, $path = '') {
|
protected function parseOutput(array $lines, string $path = ''): bool {
|
||||||
if (count($lines) === 0) {
|
if (count($lines) === 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -451,7 +454,7 @@ class Share extends AbstractShare {
|
||||||
* @param string $string
|
* @param string $string
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function escape($string) {
|
protected function escape(string $string): string {
|
||||||
return escapeshellarg($string);
|
return escapeshellarg($string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -459,7 +462,7 @@ class Share extends AbstractShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function escapePath($path) {
|
protected function escapePath(string $path): string {
|
||||||
$this->verifyPath($path);
|
$this->verifyPath($path);
|
||||||
if ($path === '/') {
|
if ($path === '/') {
|
||||||
$path = '';
|
$path = '';
|
||||||
|
|
@ -474,12 +477,12 @@ class Share extends AbstractShare {
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function escapeLocalPath($path) {
|
protected function escapeLocalPath(string $path): string {
|
||||||
$path = str_replace('"', '\"', $path);
|
$path = str_replace('"', '\"', $path);
|
||||||
return '"' . $path . '"';
|
return '"' . $path . '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getAcls($path) {
|
protected function getAcls(string $path): array {
|
||||||
$commandPath = $this->system->getSmbcAclsPath();
|
$commandPath = $this->system->getSmbcAclsPath();
|
||||||
if (!$commandPath) {
|
if (!$commandPath) {
|
||||||
return [];
|
return [];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue