mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-11-16 18:25:13 +00:00
Net_SFTP_Stream: Add limited support for notifications and...
...add NET_SFTP_STREAM_LOGGING
This commit is contained in:
parent
1c7fb5bd67
commit
a47c1c3980
@ -126,11 +126,22 @@ class Net_SFTP_Stream {
|
|||||||
*/
|
*/
|
||||||
var $context;
|
var $context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification callback function
|
||||||
|
*
|
||||||
|
* @var Callable
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
var $notification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path Parser
|
* Path Parser
|
||||||
*
|
*
|
||||||
* Extract a path from a URI and actually connect to an SSH server if appropriate
|
* Extract a path from a URI and actually connect to an SSH server if appropriate
|
||||||
*
|
*
|
||||||
|
* If "notification" is set as a context parameter the message code for successful login is
|
||||||
|
* NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE.
|
||||||
|
*
|
||||||
* @param String $path
|
* @param String $path
|
||||||
* @return String
|
* @return String
|
||||||
* @access private
|
* @access private
|
||||||
@ -143,6 +154,11 @@ class Net_SFTP_Stream {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$context = stream_context_get_params($this->context);
|
||||||
|
if (isset($context['notification'])) {
|
||||||
|
$this->notification = $context['notification'];
|
||||||
|
}
|
||||||
|
|
||||||
if ($host[0] == '$') {
|
if ($host[0] == '$') {
|
||||||
$host = substr($host, 1);
|
$host = substr($host, 1);
|
||||||
global $$host;
|
global $$host;
|
||||||
@ -181,8 +197,27 @@ class Net_SFTP_Stream {
|
|||||||
$this->sftp = self::$instances[$host][$port][$user][(string) $pass];
|
$this->sftp = self::$instances[$host][$port][$user][(string) $pass];
|
||||||
} else {
|
} else {
|
||||||
$this->sftp = new Net_SFTP($host, isset($port) ? $port : 22);
|
$this->sftp = new Net_SFTP($host, isset($port) ? $port : 22);
|
||||||
if (!$this->sftp->login($user, $pass)) {
|
if (isset($this->notification) && is_callable($this->notification)) {
|
||||||
return false;
|
/* if !is_callable($this->notification) we could do this:
|
||||||
|
|
||||||
|
user_error('fopen(): failed to call user notifier', E_USER_WARNING);
|
||||||
|
|
||||||
|
the ftp wrapper gives errors like that when the notifier isn't callable.
|
||||||
|
i've opted not to do that, however, since the ftp wrapper gives the line
|
||||||
|
on which the fopen occurred as the line number - not the line that the
|
||||||
|
user_error is on.
|
||||||
|
*/
|
||||||
|
call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
|
||||||
|
call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
|
||||||
|
if (!$this->sftp->login($user, $pass)) {
|
||||||
|
call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0);
|
||||||
|
} else {
|
||||||
|
if (!$this->sftp->login($user, $pass)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self::$instances[$host][$port][$user][(string) $pass] = $this->sftp;
|
self::$instances[$host][$port][$user][(string) $pass] = $this->sftp;
|
||||||
}
|
}
|
||||||
@ -201,7 +236,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_open($path, $mode, $options, &$opened_path)
|
function _stream_open($path, $mode, $options, &$opened_path)
|
||||||
{
|
{
|
||||||
$path = $this->_parse_path($path);
|
$path = $this->_parse_path($path);
|
||||||
|
|
||||||
@ -239,7 +274,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_read($count)
|
function _stream_read($count)
|
||||||
{
|
{
|
||||||
switch ($this->mode) {
|
switch ($this->mode) {
|
||||||
case 'w':
|
case 'w':
|
||||||
@ -256,7 +291,16 @@ class Net_SFTP_Stream {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
$result = $this->sftp->get($this->path, false, $this->pos, $count);
|
$result = $this->sftp->get($this->path, false, $this->pos, $count);
|
||||||
if (empty($result)) {
|
if (isset($this->notification) && is_callable($this->notification)) {
|
||||||
|
if ($result === false) {
|
||||||
|
call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// seems that PHP calls stream_read in 8k chunks
|
||||||
|
call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($result)) { // ie. false or empty string
|
||||||
$this->eof = true;
|
$this->eof = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -272,7 +316,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_write($data)
|
function _stream_write($data)
|
||||||
{
|
{
|
||||||
switch ($this->mode) {
|
switch ($this->mode) {
|
||||||
case 'r':
|
case 'r':
|
||||||
@ -280,6 +324,15 @@ class Net_SFTP_Stream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->sftp->put($this->path, $data, NET_SFTP_STRING, $this->pos);
|
$result = $this->sftp->put($this->path, $data, NET_SFTP_STRING, $this->pos);
|
||||||
|
if (isset($this->notification) && is_callable($this->notification)) {
|
||||||
|
if (!$result) {
|
||||||
|
call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// seems that PHP splits up strings into 8k blocks before calling stream_write
|
||||||
|
call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data));
|
||||||
|
}
|
||||||
|
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -297,7 +350,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Integer
|
* @return Integer
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_tell()
|
function _stream_tell()
|
||||||
{
|
{
|
||||||
return $this->pos;
|
return $this->pos;
|
||||||
}
|
}
|
||||||
@ -315,7 +368,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_eof()
|
function _stream_eof()
|
||||||
{
|
{
|
||||||
return $this->eof;
|
return $this->eof;
|
||||||
}
|
}
|
||||||
@ -328,7 +381,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_seek($offset, $whence)
|
function _stream_seek($offset, $whence)
|
||||||
{
|
{
|
||||||
switch ($whence) {
|
switch ($whence) {
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
@ -357,7 +410,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_metadata($path, $option, $var)
|
function _stream_metadata($path, $option, $var)
|
||||||
{
|
{
|
||||||
$path = $this->_parse_path($path);
|
$path = $this->_parse_path($path);
|
||||||
if ($path === false) {
|
if ($path === false) {
|
||||||
@ -389,7 +442,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Resource
|
* @return Resource
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_cast($cast_as)
|
function _stream_cast($cast_as)
|
||||||
{
|
{
|
||||||
return $this->sftp->fsock;
|
return $this->sftp->fsock;
|
||||||
}
|
}
|
||||||
@ -401,7 +454,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_lock($operation)
|
function _stream_lock($operation)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -418,7 +471,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function rename($path_from, $path_to)
|
function _rename($path_from, $path_to)
|
||||||
{
|
{
|
||||||
$path1 = parse_url($path_from);
|
$path1 = parse_url($path_from);
|
||||||
$path2 = parse_url($path_to);
|
$path2 = parse_url($path_to);
|
||||||
@ -457,7 +510,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function dir_opendir($path, $options)
|
function _dir_opendir($path, $options)
|
||||||
{
|
{
|
||||||
$path = $this->_parse_path($path);
|
$path = $this->_parse_path($path);
|
||||||
if ($path === false) {
|
if ($path === false) {
|
||||||
@ -474,7 +527,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function dir_readdir()
|
function _dir_readdir()
|
||||||
{
|
{
|
||||||
if (isset($this->entries[$this->pos])) {
|
if (isset($this->entries[$this->pos])) {
|
||||||
return $this->entries[$this->pos++];
|
return $this->entries[$this->pos++];
|
||||||
@ -488,7 +541,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function dir_rewinddir()
|
function _dir_rewinddir()
|
||||||
{
|
{
|
||||||
$this->pos = 0;
|
$this->pos = 0;
|
||||||
return true;
|
return true;
|
||||||
@ -500,7 +553,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function dir_closedir()
|
function _dir_closedir()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -516,7 +569,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function mkdir($path, $mode, $options)
|
function _mkdir($path, $mode, $options)
|
||||||
{
|
{
|
||||||
$path = $this->_parse_path($path);
|
$path = $this->_parse_path($path);
|
||||||
if ($path === false) {
|
if ($path === false) {
|
||||||
@ -540,7 +593,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function rmdir($path, $options)
|
function _rmdir($path, $options)
|
||||||
{
|
{
|
||||||
$path = $this->_parse_path($path);
|
$path = $this->_parse_path($path);
|
||||||
if ($path === false) {
|
if ($path === false) {
|
||||||
@ -558,7 +611,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_flush()
|
function _stream_flush()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -569,7 +622,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_stat()
|
function _stream_stat()
|
||||||
{
|
{
|
||||||
$results = $this->sftp->stat($this->path);
|
$results = $this->sftp->stat($this->path);
|
||||||
if ($results === false) {
|
if ($results === false) {
|
||||||
@ -585,7 +638,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function unlink($path)
|
function _unlink($path)
|
||||||
{
|
{
|
||||||
$path = $this->_parse_path($path);
|
$path = $this->_parse_path($path);
|
||||||
if ($path === false) {
|
if ($path === false) {
|
||||||
@ -607,7 +660,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Mixed
|
* @return Mixed
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function url_stat($path, $flags)
|
function _url_stat($path, $flags)
|
||||||
{
|
{
|
||||||
$path = $this->_parse_path($path);
|
$path = $this->_parse_path($path);
|
||||||
if ($path === false) {
|
if ($path === false) {
|
||||||
@ -629,7 +682,7 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_truncate($new_size)
|
function _stream_truncate($new_size)
|
||||||
{
|
{
|
||||||
if (!$this->sftp->truncate($this->path, $new_size)) {
|
if (!$this->sftp->truncate($this->path, $new_size)) {
|
||||||
return false;
|
return false;
|
||||||
@ -653,10 +706,54 @@ class Net_SFTP_Stream {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function stream_set_option($option, $arg1, $arg2)
|
function _stream_set_option($option, $arg1, $arg2)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close an resource
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function _stream_close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __call Magic Method
|
||||||
|
*
|
||||||
|
* When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you.
|
||||||
|
* Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function
|
||||||
|
* lets you figure that out.
|
||||||
|
*
|
||||||
|
* If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not
|
||||||
|
* NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method.
|
||||||
|
*
|
||||||
|
* @param String
|
||||||
|
* @param Array
|
||||||
|
* @return Mixed
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function __call($name, $arguments)
|
||||||
|
{
|
||||||
|
if (defined('NET_SFTP_STREAM_LOGGING')) {
|
||||||
|
echo $name . '(';
|
||||||
|
$last = count($arguments) - 1;
|
||||||
|
foreach ($arguments as $i => $argument) {
|
||||||
|
var_export($argument);
|
||||||
|
if ($i != $last) {
|
||||||
|
echo ',';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo ")\r\n";
|
||||||
|
}
|
||||||
|
$name = '_' . $name;
|
||||||
|
if (!method_exists($this, $name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return call_user_func_array(array($this, $name), $arguments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_wrapper_register('sftp', 'Net_SFTP_Stream');
|
stream_wrapper_register('sftp', 'Net_SFTP_Stream');
|
Loading…
Reference in New Issue
Block a user