more type hints

This commit is contained in:
Robin Appelman 2021-03-09 18:01:42 +01:00
commit e9f6d00a93
28 changed files with 343 additions and 530 deletions

View file

@ -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;
} }
} }

View file

@ -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';
} }

View file

@ -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) : '';
} }

View file

@ -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)) {

View file

@ -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

View file

@ -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[]

View file

@ -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

View file

@ -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);
} }

View file

@ -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

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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';
} }

View file

@ -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;

View file

@ -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();
} }
} }

View file

@ -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())) {

View file

@ -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);

View file

@ -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) {

View file

@ -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);

View file

@ -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);
} }

View file

@ -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];
} }

View file

@ -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();

View file

@ -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);

View file

@ -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);
} }

View file

@ -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');

View file

@ -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, '|')) {

View file

@ -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;
} }

View file

@ -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);
} }
} }

View file

@ -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 [];