function _realpath($path)
{
if ($this->pwd === false) {
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
return false;
}
$response = $this->_get_sftp_packet();
switch ($this->packet_type) {
case NET_SFTP_NAME:
// although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following
// should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks
// at is the first part and that part is defined the same in SFTP versions 3 through 6.
Strings::shift($response, 4);
// skip over the count - it should be 1, anyway
if (strlen($response) < 4) {
return false;
}
extract(unpack('Nlength', Strings::shift($response, 4)));
return Strings::shift($response, $length);
case NET_SFTP_STATUS:
$this->_logError($response);
return false;
default:
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
}
}
if ($path[0] != '/') {
$path = $this->pwd . '/' . $path;
}
$path = explode('/', $path);
$new = array();
foreach ($path as $dir) {
if (!strlen($dir)) {
continue;
}
switch ($dir) {
case '..':
array_pop($new);
case '.':
break;
default:
$new[] = $dir;
}
}
return '/' . implode('/', $new);
}