mirror of
https://codeberg.org/icewind/SMB.git
synced 2026-06-04 01:34:07 +02:00
Pass path and error code to exceptions
This commit is contained in:
parent
cd5261a86d
commit
77c30c698f
4 changed files with 80 additions and 50 deletions
|
|
@ -7,4 +7,25 @@
|
||||||
|
|
||||||
namespace Icewind\SMB\Exception;
|
namespace Icewind\SMB\Exception;
|
||||||
|
|
||||||
class InvalidRequestException extends Exception {}
|
class InvalidRequestException extends Exception {
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path
|
||||||
|
* @param int $code
|
||||||
|
*/
|
||||||
|
public function __construct($path, $code = 0) {
|
||||||
|
parent::__construct('Invalid request for ' . $path, $code);
|
||||||
|
$this->path = $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getPath() {
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,32 +27,36 @@ class NativeState {
|
||||||
|
|
||||||
protected $connected = false;
|
protected $connected = false;
|
||||||
|
|
||||||
protected function handleError() {
|
protected function handleError($path) {
|
||||||
$error = smbclient_state_errno($this->state);
|
$error = smbclient_state_errno($this->state);
|
||||||
switch ($error) {
|
switch ($error) {
|
||||||
// see error.h
|
// see error.h
|
||||||
case 0;
|
case 0;
|
||||||
return;
|
return;
|
||||||
case 1:
|
case 1:
|
||||||
throw new ForbiddenException();
|
throw new ForbiddenException($path, $error);
|
||||||
case 2:
|
case 2:
|
||||||
throw new NotFoundException();
|
throw new NotFoundException($path, $error);
|
||||||
case 17:
|
case 17:
|
||||||
throw new AlreadyExistsException();
|
throw new AlreadyExistsException($path, $error);
|
||||||
case 20:
|
case 20:
|
||||||
throw new InvalidTypeException();
|
throw new InvalidTypeException($path, $error);
|
||||||
case 21:
|
case 21:
|
||||||
throw new InvalidTypeException();
|
throw new InvalidTypeException($path, $error);
|
||||||
case 39:
|
case 39:
|
||||||
throw new NotEmptyException();
|
throw new NotEmptyException($path, $error);
|
||||||
default:
|
default:
|
||||||
throw new Exception('Unknown error (' . $error . ')');
|
$message = 'Unknown error (' . $error . ')';
|
||||||
|
if ($path) {
|
||||||
|
$message .= ' for ' . $path;
|
||||||
|
}
|
||||||
|
throw new Exception($message, $error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function testResult($result) {
|
protected function testResult($result, $path) {
|
||||||
if ($result === false or $result === null) {
|
if ($result === false or $result === null) {
|
||||||
$this->handleError();
|
$this->handleError($path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +73,7 @@ class NativeState {
|
||||||
$this->state = smbclient_state_new();
|
$this->state = smbclient_state_new();
|
||||||
$result = @smbclient_state_init($this->state, $workGroup, $user, $password);
|
$result = @smbclient_state_init($this->state, $workGroup, $user, $password);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, '');
|
||||||
$this->connected = true;
|
$this->connected = true;
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +85,7 @@ class NativeState {
|
||||||
public function opendir($uri) {
|
public function opendir($uri) {
|
||||||
$result = @smbclient_opendir($this->state, $uri);
|
$result = @smbclient_opendir($this->state, $uri);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,7 +96,7 @@ class NativeState {
|
||||||
public function readdir($dir) {
|
public function readdir($dir) {
|
||||||
$result = @smbclient_readdir($this->state, $dir);
|
$result = @smbclient_readdir($this->state, $dir);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $dir);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +107,7 @@ class NativeState {
|
||||||
public function closedir($dir) {
|
public function closedir($dir) {
|
||||||
$result = smbclient_closedir($this->state, $dir);
|
$result = smbclient_closedir($this->state, $dir);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $dir);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,7 +119,7 @@ class NativeState {
|
||||||
public function rename($old, $new) {
|
public function rename($old, $new) {
|
||||||
$result = @smbclient_rename($this->state, $old, $this->state, $new);
|
$result = @smbclient_rename($this->state, $old, $this->state, $new);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $new);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,7 +130,7 @@ class NativeState {
|
||||||
public function unlink($uri) {
|
public function unlink($uri) {
|
||||||
$result = @smbclient_unlink($this->state, $uri);
|
$result = @smbclient_unlink($this->state, $uri);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,7 +142,7 @@ class NativeState {
|
||||||
public function mkdir($uri, $mask = 0777) {
|
public function mkdir($uri, $mask = 0777) {
|
||||||
$result = @smbclient_mkdir($this->state, $uri, $mask);
|
$result = @smbclient_mkdir($this->state, $uri, $mask);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,7 +153,7 @@ class NativeState {
|
||||||
public function rmdir($uri) {
|
public function rmdir($uri) {
|
||||||
$result = @smbclient_rmdir($this->state, $uri);
|
$result = @smbclient_rmdir($this->state, $uri);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,7 +164,7 @@ class NativeState {
|
||||||
public function stat($uri) {
|
public function stat($uri) {
|
||||||
$result = @smbclient_stat($this->state, $uri);
|
$result = @smbclient_stat($this->state, $uri);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,7 +175,7 @@ class NativeState {
|
||||||
public function fstat($file) {
|
public function fstat($file) {
|
||||||
$result = @smbclient_fstat($this->state, $file);
|
$result = @smbclient_fstat($this->state, $file);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $file);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,7 +188,7 @@ class NativeState {
|
||||||
public function open($uri, $mode, $mask = 0666) {
|
public function open($uri, $mode, $mask = 0666) {
|
||||||
$result = @smbclient_open($this->state, $uri, $mode, $mask);
|
$result = @smbclient_open($this->state, $uri, $mode, $mask);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +200,7 @@ class NativeState {
|
||||||
public function create($uri, $mask = 0666) {
|
public function create($uri, $mask = 0666) {
|
||||||
$result = @smbclient_creat($this->state, $uri, $mask);
|
$result = @smbclient_creat($this->state, $uri, $mask);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,7 +212,7 @@ class NativeState {
|
||||||
public function read($file, $bytes) {
|
public function read($file, $bytes) {
|
||||||
$result = @smbclient_read($this->state, $file, $bytes);
|
$result = @smbclient_read($this->state, $file, $bytes);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $file);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,7 +225,7 @@ class NativeState {
|
||||||
public function write($file, $data, $length = null) {
|
public function write($file, $data, $length = null) {
|
||||||
$result = @smbclient_write($this->state, $file, $data, $length);
|
$result = @smbclient_write($this->state, $file, $data, $length);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $file);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,7 +238,7 @@ class NativeState {
|
||||||
public function lseek($file, $offset, $whence = SEEK_SET) {
|
public function lseek($file, $offset, $whence = SEEK_SET) {
|
||||||
$result = @smbclient_lseek($this->state, $file, $offset, $whence);
|
$result = @smbclient_lseek($this->state, $file, $offset, $whence);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $file);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,14 +250,14 @@ class NativeState {
|
||||||
public function ftruncate($file, $size) {
|
public function ftruncate($file, $size) {
|
||||||
$result = @smbclient_ftruncate($this->state, $file, $size);
|
$result = @smbclient_ftruncate($this->state, $file, $size);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $file);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close($file) {
|
public function close($file) {
|
||||||
$result = @smbclient_close($this->state, $file);
|
$result = @smbclient_close($this->state, $file);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $file);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,7 +269,7 @@ class NativeState {
|
||||||
public function getxattr($uri, $key) {
|
public function getxattr($uri, $key) {
|
||||||
$result = @smbclient_getxattr($this->state, $uri, $key);
|
$result = @smbclient_getxattr($this->state, $uri, $key);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,7 +283,7 @@ class NativeState {
|
||||||
public function setxattr($uri, $key, $value, $flags = 0) {
|
public function setxattr($uri, $key, $value, $flags = 0) {
|
||||||
$result = @smbclient_setxattr($this->state, $uri, $key, $value, $flags);
|
$result = @smbclient_setxattr($this->state, $uri, $key, $value, $flags);
|
||||||
|
|
||||||
$this->testResult($result);
|
$this->testResult($result, $uri);
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,12 @@ class Parser {
|
||||||
$this->timeZone = $timeZone;
|
$this->timeZone = $timeZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkForError($output) {
|
public function checkForError($output, $path) {
|
||||||
if (count($output) === 0) {
|
if (count($output) === 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (strpos($output[0], 'does not exist')) {
|
if (strpos($output[0], 'does not exist')) {
|
||||||
throw new NotFoundException();
|
throw new NotFoundException($path);
|
||||||
}
|
}
|
||||||
$parts = explode(' ', $output[0]);
|
$parts = explode(' ', $output[0]);
|
||||||
$error = false;
|
$error = false;
|
||||||
|
|
@ -45,18 +45,22 @@ class Parser {
|
||||||
case ErrorCodes::PathNotFound:
|
case ErrorCodes::PathNotFound:
|
||||||
case ErrorCodes::ObjectNotFound:
|
case ErrorCodes::ObjectNotFound:
|
||||||
case ErrorCodes::NoSuchFile:
|
case ErrorCodes::NoSuchFile:
|
||||||
throw new NotFoundException();
|
throw new NotFoundException($path);
|
||||||
case ErrorCodes::NameCollision:
|
case ErrorCodes::NameCollision:
|
||||||
throw new AlreadyExistsException();
|
throw new AlreadyExistsException($path);
|
||||||
case ErrorCodes::AccessDenied:
|
case ErrorCodes::AccessDenied:
|
||||||
throw new AccessDeniedException();
|
throw new AccessDeniedException($path);
|
||||||
case ErrorCodes::DirectoryNotEmpty:
|
case ErrorCodes::DirectoryNotEmpty:
|
||||||
throw new NotEmptyException();
|
throw new NotEmptyException($path);
|
||||||
case ErrorCodes::FileIsADirectory:
|
case ErrorCodes::FileIsADirectory:
|
||||||
case ErrorCodes::NotADirectory:
|
case ErrorCodes::NotADirectory:
|
||||||
throw new InvalidTypeException();
|
throw new InvalidTypeException($path);
|
||||||
default:
|
default:
|
||||||
throw new Exception();
|
$message = 'Unknown error (' . $error . ')';
|
||||||
|
if ($path) {
|
||||||
|
$message .= ' for ' . $path;
|
||||||
|
}
|
||||||
|
throw new Exception($message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class Share implements IShare {
|
||||||
$path = $this->escapePath($path);
|
$path = $this->escapePath($path);
|
||||||
$cmd = $command . ' ' . $path;
|
$cmd = $command . ' ' . $path;
|
||||||
$output = $this->execute($cmd);
|
$output = $this->execute($cmd);
|
||||||
return $this->parseOutput($output);
|
return $this->parseOutput($output, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -99,7 +99,7 @@ class Share implements IShare {
|
||||||
$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
|
||||||
$this->parseOutput($output);
|
$this->parseOutput($output, $path);
|
||||||
$output = $this->execute('dir');
|
$output = $this->execute('dir');
|
||||||
$this->execute('cd /');
|
$this->execute('cd /');
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ class Share implements IShare {
|
||||||
$escapedPath = $this->escapePath($path);
|
$escapedPath = $this->escapePath($path);
|
||||||
$output = $this->execute('allinfo ' . $escapedPath);
|
$output = $this->execute('allinfo ' . $escapedPath);
|
||||||
if (count($output) < 3) {
|
if (count($output) < 3) {
|
||||||
$this->parseOutput($output);
|
$this->parseOutput($output, $path);
|
||||||
}
|
}
|
||||||
$stat = $this->parser->parseStat($output);
|
$stat = $this->parser->parseStat($output);
|
||||||
return new FileInfo($path, basename($path), $stat['size'], $stat['mtime'], $stat['mode']);
|
return new FileInfo($path, basename($path), $stat['size'], $stat['mtime'], $stat['mode']);
|
||||||
|
|
@ -167,7 +167,7 @@ class Share implements IShare {
|
||||||
} catch (NotFoundException $e2) {
|
} catch (NotFoundException $e2) {
|
||||||
throw $e;
|
throw $e;
|
||||||
} catch (\Exception $e2) {
|
} catch (\Exception $e2) {
|
||||||
throw new InvalidTypeException();
|
throw new InvalidTypeException($path);
|
||||||
}
|
}
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +188,7 @@ class Share implements IShare {
|
||||||
$path2 = $this->escapePath($to);
|
$path2 = $this->escapePath($to);
|
||||||
$cmd = 'rename ' . $path1 . ' ' . $path2;
|
$cmd = 'rename ' . $path1 . ' ' . $path2;
|
||||||
$output = $this->execute($cmd);
|
$output = $this->execute($cmd);
|
||||||
return $this->parseOutput($output);
|
return $this->parseOutput($output, $to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -205,7 +205,7 @@ class Share implements IShare {
|
||||||
$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);
|
||||||
return $this->parseOutput($output);
|
return $this->parseOutput($output, $target);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -222,7 +222,7 @@ class Share implements IShare {
|
||||||
$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);
|
||||||
return $this->parseOutput($output);
|
return $this->parseOutput($output, $source);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -308,12 +308,12 @@ class Share implements IShare {
|
||||||
// first reset the mode to normal
|
// first reset the mode to normal
|
||||||
$cmd = 'setmode ' . $path . ' -rsha';
|
$cmd = 'setmode ' . $path . ' -rsha';
|
||||||
$output = $this->execute($cmd);
|
$output = $this->execute($cmd);
|
||||||
$this->parseOutput($output);
|
$this->parseOutput($output, $path);
|
||||||
|
|
||||||
// then set the modes we want
|
// then set the modes we want
|
||||||
$cmd = 'setmode ' . $path . ' ' . $modeString;
|
$cmd = 'setmode ' . $path . ' ' . $modeString;
|
||||||
$output = $this->execute($cmd);
|
$output = $this->execute($cmd);
|
||||||
return $this->parseOutput($output);
|
return $this->parseOutput($output, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -330,7 +330,8 @@ class Share implements IShare {
|
||||||
/**
|
/**
|
||||||
* check output for errors
|
* check output for errors
|
||||||
*
|
*
|
||||||
* @param $lines
|
* @param string[] $lines
|
||||||
|
* @param string $path
|
||||||
*
|
*
|
||||||
* @throws NotFoundException
|
* @throws NotFoundException
|
||||||
* @throws \Icewind\SMB\Exception\AlreadyExistsException
|
* @throws \Icewind\SMB\Exception\AlreadyExistsException
|
||||||
|
|
@ -340,8 +341,8 @@ class Share implements IShare {
|
||||||
* @throws \Icewind\SMB\Exception\Exception
|
* @throws \Icewind\SMB\Exception\Exception
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function parseOutput($lines) {
|
protected function parseOutput($lines, $path = '') {
|
||||||
$this->parser->checkForError($lines);
|
$this->parser->checkForError($lines, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue