256        $this->max_sftp_packet = 1 << 15;
 
  258        $this->packet_types = array(
 
  259            1  => 
'NET_SFTP_INIT',
 
  260            2  => 
'NET_SFTP_VERSION',
 
  264            3  => 
'NET_SFTP_OPEN',
 
  265            4  => 
'NET_SFTP_CLOSE',
 
  266            5  => 
'NET_SFTP_READ',
 
  267            6  => 
'NET_SFTP_WRITE',
 
  268            7  => 
'NET_SFTP_LSTAT',
 
  269            9  => 
'NET_SFTP_SETSTAT',
 
  270            11 => 
'NET_SFTP_OPENDIR',
 
  271            12 => 
'NET_SFTP_READDIR',
 
  272            13 => 
'NET_SFTP_REMOVE',
 
  273            14 => 
'NET_SFTP_MKDIR',
 
  274            15 => 
'NET_SFTP_RMDIR',
 
  275            16 => 
'NET_SFTP_REALPATH',
 
  276            17 => 
'NET_SFTP_STAT',
 
  280            18 => 
'NET_SFTP_RENAME',
 
  281            19 => 
'NET_SFTP_READLINK',
 
  282            20 => 
'NET_SFTP_SYMLINK',
 
  284            101=> 
'NET_SFTP_STATUS',
 
  285            102=> 
'NET_SFTP_HANDLE',
 
  289            103=> 
'NET_SFTP_DATA',
 
  290            104=> 
'NET_SFTP_NAME',
 
  291            105=> 
'NET_SFTP_ATTRS',
 
  293            200=> 
'NET_SFTP_EXTENDED' 
  295        $this->status_codes = array(
 
  296            0 => 
'NET_SFTP_STATUS_OK',
 
  297            1 => 
'NET_SFTP_STATUS_EOF',
 
  298            2 => 
'NET_SFTP_STATUS_NO_SUCH_FILE',
 
  299            3 => 
'NET_SFTP_STATUS_PERMISSION_DENIED',
 
  300            4 => 
'NET_SFTP_STATUS_FAILURE',
 
  301            5 => 
'NET_SFTP_STATUS_BAD_MESSAGE',
 
  302            6 => 
'NET_SFTP_STATUS_NO_CONNECTION',
 
  303            7 => 
'NET_SFTP_STATUS_CONNECTION_LOST',
 
  304            8 => 
'NET_SFTP_STATUS_OP_UNSUPPORTED',
 
  305            9 => 
'NET_SFTP_STATUS_INVALID_HANDLE',
 
  306            10 => 
'NET_SFTP_STATUS_NO_SUCH_PATH',
 
  307            11 => 
'NET_SFTP_STATUS_FILE_ALREADY_EXISTS',
 
  308            12 => 
'NET_SFTP_STATUS_WRITE_PROTECT',
 
  309            13 => 
'NET_SFTP_STATUS_NO_MEDIA',
 
  310            14 => 
'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM',
 
  311            15 => 
'NET_SFTP_STATUS_QUOTA_EXCEEDED',
 
  312            16 => 
'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL',
 
  313            17 => 
'NET_SFTP_STATUS_LOCK_CONFLICT',
 
  314            18 => 
'NET_SFTP_STATUS_DIR_NOT_EMPTY',
 
  315            19 => 
'NET_SFTP_STATUS_NOT_A_DIRECTORY',
 
  316            20 => 
'NET_SFTP_STATUS_INVALID_FILENAME',
 
  317            21 => 
'NET_SFTP_STATUS_LINK_LOOP',
 
  318            22 => 
'NET_SFTP_STATUS_CANNOT_DELETE',
 
  319            23 => 
'NET_SFTP_STATUS_INVALID_PARAMETER',
 
  320            24 => 
'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY',
 
  321            25 => 
'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT',
 
  322            26 => 
'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED',
 
  323            27 => 
'NET_SFTP_STATUS_DELETE_PENDING',
 
  324            28 => 
'NET_SFTP_STATUS_FILE_CORRUPT',
 
  325            29 => 
'NET_SFTP_STATUS_OWNER_INVALID',
 
  326            30 => 
'NET_SFTP_STATUS_GROUP_INVALID',
 
  327            31 => 
'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' 
  331        $this->attributes = array(
 
  332            0x00000001 => 
'NET_SFTP_ATTR_SIZE',
 
  333            0x00000002 => 
'NET_SFTP_ATTR_UIDGID', 
 
  334            0x00000004 => 
'NET_SFTP_ATTR_PERMISSIONS',
 
  335            0x00000008 => 
'NET_SFTP_ATTR_ACCESSTIME',
 
  340              -1 << 31 => 
'NET_SFTP_ATTR_EXTENDED' 
  345        $this->open_flags = array(
 
  346            0x00000001 => 
'NET_SFTP_OPEN_READ',
 
  347            0x00000002 => 
'NET_SFTP_OPEN_WRITE',
 
  348            0x00000004 => 
'NET_SFTP_OPEN_APPEND',
 
  349            0x00000008 => 
'NET_SFTP_OPEN_CREATE',
 
  350            0x00000010 => 
'NET_SFTP_OPEN_TRUNCATE',
 
  351            0x00000020 => 
'NET_SFTP_OPEN_EXCL' 
  355        $this->file_types = array(
 
  356            1 => 
'NET_SFTP_TYPE_REGULAR',
 
  357            2 => 
'NET_SFTP_TYPE_DIRECTORY',
 
  358            3 => 
'NET_SFTP_TYPE_SYMLINK',
 
  359            4 => 
'NET_SFTP_TYPE_SPECIAL',
 
  360            5 => 
'NET_SFTP_TYPE_UNKNOWN',
 
  363            6 => 
'NET_SFTP_TYPE_SOCKET',
 
  364            7 => 
'NET_SFTP_TYPE_CHAR_DEVICE',
 
  365            8 => 
'NET_SFTP_TYPE_BLOCK_DEVICE',
 
  366            9 => 
'NET_SFTP_TYPE_FIFO' 
  376        if (!defined(
'NET_SFTP_QUEUE_SIZE')) {
 
  377            define(
'NET_SFTP_QUEUE_SIZE', 50);
 
  391        $args = func_get_args();
 
  392        if (!call_user_func_array(array(&$this, 
'_login'), $args)) {
 
  400            NET_SSH2_MSG_CHANNEL_OPEN,
 
  412        $this->channel_status[
self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
 
  421            NET_SSH2_MSG_CHANNEL_REQUEST,
 
  422            $this->server_channels[self::CHANNEL],
 
  433        $this->channel_status[
self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
 
  438            $command = 
"test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
 
  439                       "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n" .
 
  445                NET_SSH2_MSG_CHANNEL_REQUEST,
 
  446                $this->server_channels[self::CHANNEL],
 
  457            $this->channel_status[
self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
 
  465        $this->channel_status[
self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA;
 
  472        if ($this->packet_type != NET_SFTP_VERSION) {
 
  473            user_error(
'Expected SSH_FXP_VERSION');
 
  484            $this->extensions[
$key] = $value;
 
  501        $this->request_id = 1;
 
  526        switch ($this->version) {
 
  548        $this->use_stat_cache = 
false;
 
  558        $this->use_stat_cache = 
true;
 
  568        $this->stat_cache = array();
 
  595        $error = $this->status_codes[$status];
 
  597        if ($this->version > 2) {
 
  601            $this->sftp_errors[] = $error;
 
  618        if ($this->
pwd === 
false) {
 
  625            switch ($this->packet_type) {
 
  633                case NET_SFTP_STATUS:
 
  637                    user_error(
'Expected SSH_FXP_NAME or SSH_FXP_STATUS');
 
  642        if (
$path[0] != 
'/') {
 
  648        foreach (
$path as $dir) {
 
  662        return '/' . implode(
'/', $new);
 
  682        } elseif ($dir[strlen($dir) - 1] != 
'/') {
 
  699        if (!$this->
_send_sftp_packet(NET_SFTP_OPENDIR, pack(
'Na*', strlen($dir), $dir))) {
 
  705        switch ($this->packet_type) {
 
  706            case NET_SFTP_HANDLE:
 
  709            case NET_SFTP_STATUS:
 
  713                user_error(
'Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
 
  735    function nlist($dir = 
'.', $recursive = 
false)
 
  758        foreach (
$files as $value) {
 
  759            if ($value == 
'.' || $value == 
'..') {
 
  760                if ($relativeDir == 
'') {
 
  766                $temp = $this->
_nlist_helper($dir . 
'/' . $value, 
true, $relativeDir . $value . 
'/');
 
  769                $result[] = $relativeDir . $value;
 
  784    function rawlist($dir = 
'.', $recursive = 
false)
 
  787        if (!$recursive || 
$files === 
false) {
 
  794            if ($depth != 0 && 
$key == 
'..') {
 
  825        if ($dir === 
false) {
 
  830        if (!$this->
_send_sftp_packet(NET_SFTP_OPENDIR, pack(
'Na*', strlen($dir), $dir))) {
 
  835        switch ($this->packet_type) {
 
  836            case NET_SFTP_HANDLE:
 
  842            case NET_SFTP_STATUS:
 
  847                user_error(
'Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
 
  858            if (!$this->
_send_sftp_packet(NET_SFTP_READDIR, pack(
'Na*', strlen($handle), $handle))) {
 
  863            switch ($this->packet_type) {
 
  866                    for (
$i = 0; 
$i < $count; 
$i++) {
 
  878                        $contents[$shortname] = 
$attributes + array(
'filename' => $shortname);
 
  880                        if (isset(
$attributes[
'type']) && 
$attributes[
'type'] == NET_SFTP_TYPE_DIRECTORY && ($shortname != 
'.' && $shortname != 
'..')) {
 
  883                            if ($shortname == 
'..') {
 
  884                                $temp = $this->
_realpath($dir . 
'/..') . 
'/.';
 
  886                                $temp = $dir . 
'/' . $shortname;
 
  894                case NET_SFTP_STATUS:
 
  896                    if ($status != NET_SFTP_STATUS_EOF) {
 
  902                    user_error(
'Expected SSH_FXP_NAME or SSH_FXP_STATUS');
 
  911        if (count($this->sortOptions)) {
 
  912            uasort($contents, array(&$this, 
'_comparator'));
 
  915        return $raw ? $contents : array_keys($contents);
 
  931            case $a[
'filename'] === 
'.' || $b[
'filename'] === 
'.':
 
  932                if ($a[
'filename'] === $b[
'filename']) {
 
  935                return $a[
'filename'] === 
'.' ? -1 : 1;
 
  936            case $a[
'filename'] === 
'..' || $b[
'filename'] === 
'..':
 
  937                if ($a[
'filename'] === $b[
'filename']) {
 
  940                return $a[
'filename'] === 
'..' ? -1 : 1;
 
  941            case isset($a[
'type']) && $a[
'type'] === NET_SFTP_TYPE_DIRECTORY:
 
  942                if (!isset($b[
'type'])) {
 
  945                if ($b[
'type'] !== $a[
'type']) {
 
  949            case isset($b[
'type']) && $b[
'type'] === NET_SFTP_TYPE_DIRECTORY:
 
  952        foreach ($this->sortOptions as $sort => $order) {
 
  953            if (!isset($a[$sort]) || !isset($b[$sort])) {
 
  954                if (isset($a[$sort])) {
 
  957                if (isset($b[$sort])) {
 
  964                    $result = strcasecmp($a[
'filename'], $b[
'filename']);
 
  974                    if ($a[$sort] === $b[$sort]) {
 
  977                    return $order === SORT_ASC ? $a[$sort] - $b[$sort] : $b[$sort] - $a[$sort];
 
 1004        $this->sortOptions = array();
 
 1005        $args = func_get_args();
 
 1009        $len = count($args) & 0x7FFFFFFE;
 
 1010        for (
$i = 0; 
$i < $len; 
$i+=2) {
 
 1011            $this->sortOptions[$args[
$i]] = $args[
$i + 1];
 
 1013        if (!count($this->sortOptions)) {
 
 1014            $this->sortOptions = array(
'bogus' => 
true);
 
 1049        if ($this->use_stat_cache === 
false) {
 
 1054        $dirs = explode(
'/', preg_replace(
'#^/|/(?=/)|/$#', 
'', 
$path));
 
 1057        $max = count($dirs) - 1;
 
 1058        foreach ($dirs as 
$i => $dir) {
 
 1062            if (is_object($temp)) {
 
 1065            if (!isset($temp[$dir])) {
 
 1066                $temp[$dir] = array();
 
 1069                if (is_object($temp[$dir])) {
 
 1070                    if (!isset($value->stat) && isset($temp[$dir]->
stat)) {
 
 1071                        $value->stat = $temp[$dir]->stat;
 
 1073                    if (!isset($value->lstat) && isset($temp[$dir]->
lstat)) {
 
 1074                        $value->lstat = $temp[$dir]->lstat;
 
 1077                $temp[$dir] = $value;
 
 1080            $temp = &$temp[$dir];
 
 1093        $dirs = explode(
'/', preg_replace(
'#^/|/(?=/)|/$#', 
'', 
$path));
 
 1096        $max = count($dirs) - 1;
 
 1097        foreach ($dirs as 
$i => $dir) {
 
 1102            if (!isset($temp[$dir])) {
 
 1105            $temp = &$temp[$dir];
 
 1120        $dirs = explode(
'/', preg_replace(
'#^/|/(?=/)|/$#', 
'', 
$path));
 
 1123        foreach ($dirs as $dir) {
 
 1124            if (!isset($temp[$dir])) {
 
 1127            $temp = &$temp[$dir];
 
 1152        if ($this->use_stat_cache) {
 
 1163        if ($stat === 
false) {
 
 1167        if (isset($stat[
'type'])) {
 
 1168            if ($stat[
'type'] == NET_SFTP_TYPE_DIRECTORY) {
 
 1177            NET_SFTP_TYPE_DIRECTORY :
 
 1178            NET_SFTP_TYPE_REGULAR;
 
 1181        if ($stat[
'type'] == NET_SFTP_TYPE_DIRECTORY) {
 
 1209        if ($this->use_stat_cache) {
 
 1220        if ($lstat === 
false) {
 
 1224        if (isset($lstat[
'type'])) {
 
 1225            if ($lstat[
'type'] == NET_SFTP_TYPE_DIRECTORY) {
 
 1234        if ($lstat != $stat) {
 
 1235            $lstat = array_merge($lstat, array(
'type' => NET_SFTP_TYPE_SYMLINK));
 
 1242            NET_SFTP_TYPE_DIRECTORY :
 
 1243            NET_SFTP_TYPE_REGULAR;
 
 1246        if ($lstat[
'type'] == NET_SFTP_TYPE_DIRECTORY) {
 
 1274        switch ($this->packet_type) {
 
 1275            case NET_SFTP_ATTRS:
 
 1277            case NET_SFTP_STATUS:
 
 1282        user_error(
'Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
 
 1296        $attr = pack(
'N3', NET_SFTP_ATTR_SIZE, $new_size / 4294967296, $new_size); 
 
 1323        if (!isset(
$time)) {
 
 1326        if (!isset($atime)) {
 
 1330        $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_EXCL;
 
 1331        $attr = pack(
'N3', NET_SFTP_ATTR_ACCESSTIME, 
$time, $atime);
 
 1338        switch ($this->packet_type) {
 
 1339            case NET_SFTP_HANDLE:
 
 1341            case NET_SFTP_STATUS:
 
 1345                user_error(
'Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
 
 1367        $attr = pack(
'N3', NET_SFTP_ATTR_UIDGID, $uid, -1);
 
 1385        $attr = pack(
'N3', NET_SFTP_ATTR_UIDGID, -1, $gid);
 
 1404        if (is_string($mode) && is_int(
$filename)) {
 
 1410        $attr = pack(
'N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);
 
 1428        switch ($this->packet_type) {
 
 1429            case NET_SFTP_ATTRS:
 
 1431                return $attrs[
'permissions'];
 
 1432            case NET_SFTP_STATUS:
 
 1437        user_error(
'Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
 
 1484        if ($this->packet_type != NET_SFTP_STATUS) {
 
 1485            user_error(
'Expected SSH_FXP_STATUS');
 
 1490        if ($status != NET_SFTP_STATUS_OK) {
 
 1517        if ($entries === 
false) {
 
 1523        if (empty($entries)) {
 
 1527        unset($entries[
'.'], $entries[
'..']);
 
 1528        foreach ($entries as 
$filename => $props) {
 
 1529            if (!isset($props[
'type'])) {
 
 1534            if ($props[
'type'] == NET_SFTP_TYPE_DIRECTORY) {
 
 1539                if (!$this->
_send_sftp_packet(NET_SFTP_SETSTAT, pack(
'Na*a*', strlen($temp), $temp, $attr))) {
 
 1545                if (
$i >= NET_SFTP_QUEUE_SIZE) {
 
 1560        if (
$i >= NET_SFTP_QUEUE_SIZE) {
 
 1585        if (!$this->
_send_sftp_packet(NET_SFTP_READLINK, pack(
'Na*', strlen($link), $link))) {
 
 1590        switch ($this->packet_type) {
 
 1593            case NET_SFTP_STATUS:
 
 1597                user_error(
'Expected SSH_FXP_NAME or SSH_FXP_STATUS');
 
 1630        $packet = pack(
'Na*Na*', strlen(
$target), 
$target, strlen($link), $link);
 
 1636        if ($this->packet_type != NET_SFTP_STATUS) {
 
 1637            user_error(
'Expected SSH_FXP_STATUS');
 
 1642        if ($status != NET_SFTP_STATUS_OK) {
 
 1657    function mkdir($dir, $mode = -1, $recursive = 
false)
 
 1666        $attr = $mode == -1 ? 
"\0\0\0\0" : pack(
'N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);
 
 1669            $dirs = explode(
'/', preg_replace(
'#/(?=/)|/$#', 
'', $dir));
 
 1670            if (empty($dirs[0])) {
 
 1672                $dirs[0] = 
'/' . $dirs[0];
 
 1674            for (
$i = 0; 
$i < count($dirs); 
$i++) {
 
 1675                $temp = array_slice($dirs, 0, 
$i + 1);
 
 1676                $temp = implode(
'/', $temp);
 
 1694        if (!$this->
_send_sftp_packet(NET_SFTP_MKDIR, pack(
'Na*a*', strlen($dir), $dir, $attr))) {
 
 1699        if ($this->packet_type != NET_SFTP_STATUS) {
 
 1700            user_error(
'Expected SSH_FXP_STATUS');
 
 1705        if ($status != NET_SFTP_STATUS_OK) {
 
 1727        if ($dir === 
false) {
 
 1731        if (!$this->
_send_sftp_packet(NET_SFTP_RMDIR, pack(
'Na*', strlen($dir), $dir))) {
 
 1736        if ($this->packet_type != NET_SFTP_STATUS) {
 
 1737            user_error(
'Expected SSH_FXP_STATUS');
 
 1742        if ($status != NET_SFTP_STATUS_OK) {
 
 1802    function put($remote_file, 
$data, $mode = self::SOURCE_STRING, 
$start = -1, $local_start = -1, $progressCallback = 
null)
 
 1808        $remote_file = $this->
_realpath($remote_file);
 
 1809        if ($remote_file === 
false) {
 
 1815        $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE;
 
 1822        } elseif ($mode & self::RESUME) {
 
 1828            $flags|= NET_SFTP_OPEN_TRUNCATE;
 
 1831        $packet = pack(
'Na*N2', strlen($remote_file), $remote_file, $flags, 0);
 
 1837        switch ($this->packet_type) {
 
 1838            case NET_SFTP_HANDLE:
 
 1841            case NET_SFTP_STATUS:
 
 1845                user_error(
'Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
 
 1850        $dataCallback = 
false;
 
 1853                if (!is_callable(
$data)) {
 
 1854                    user_error(
"\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
 
 1856                $dataCallback = 
$data;
 
 1859            case is_resource(
$data):
 
 1865                    user_error(
"$data is not a valid file");
 
 1868                $fp = @fopen(
$data, 
'rb');
 
 1876            $size = $stat[
'size'];
 
 1878            if ($local_start >= 0) {
 
 1879                fseek($fp, $local_start);
 
 1880                $size-= $local_start;
 
 1882        } elseif ($dataCallback) {
 
 1891        $sftp_packet_size = 4096; 
 
 1893        $sftp_packet_size-= strlen($handle) + 25;
 
 1895        while ($dataCallback || $sent < 
$size) {
 
 1896            if ($dataCallback) {
 
 1897                $temp = call_user_func($dataCallback, $sftp_packet_size);
 
 1898                if (is_null($temp)) {
 
 1902                $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr(
$data, $sent, $sftp_packet_size);
 
 1904            $subtemp = $offset + $sent;
 
 1905            $packet = pack(
'Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
 
 1907                if ($mode & self::SOURCE_LOCAL_FILE) {
 
 1912            $sent+= strlen($temp);
 
 1913            if (is_callable($progressCallback)) {
 
 1914                call_user_func($progressCallback, $sent);
 
 1919            if (
$i == NET_SFTP_QUEUE_SIZE) {
 
 1929            if ($mode & self::SOURCE_LOCAL_FILE) {
 
 1936        if ($mode & self::SOURCE_LOCAL_FILE) {
 
 1957            if ($this->packet_type != NET_SFTP_STATUS) {
 
 1958                user_error(
'Expected SSH_FXP_STATUS');
 
 1963            if ($status != NET_SFTP_STATUS_OK) {
 
 1981        if (!$this->
_send_sftp_packet(NET_SFTP_CLOSE, pack(
'Na*', strlen($handle), $handle))) {
 
 1988        if ($this->packet_type != NET_SFTP_STATUS) {
 
 1989            user_error(
'Expected SSH_FXP_STATUS');
 
 1994        if ($status != NET_SFTP_STATUS_OK) {
 
 2018    function get($remote_file, $local_file = 
false, $offset = 0, $length = -1)
 
 2024        $remote_file = $this->
_realpath($remote_file);
 
 2025        if ($remote_file === 
false) {
 
 2029        $packet = pack(
'Na*N2', strlen($remote_file), $remote_file, NET_SFTP_OPEN_READ, 0);
 
 2035        switch ($this->packet_type) {
 
 2036            case NET_SFTP_HANDLE:
 
 2039            case NET_SFTP_STATUS: 
 
 2043                user_error(
'Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
 
 2047        if (is_resource($local_file)) {
 
 2050            $res_offset = $stat[
'size'];
 
 2053            if ($local_file !== 
false) {
 
 2054                $fp = fopen($local_file, 
'wb');
 
 2063        $fclose_check = $local_file !== 
false && !is_resource($local_file);
 
 2066        $size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length;
 
 2068            $packet = pack(
'Na*N3', strlen($handle), $handle, $offset / 4294967296, $offset, 
$size);
 
 2070                if ($fclose_check) {
 
 2077            switch ($this->packet_type) {
 
 2080                    $offset+= strlen($temp);
 
 2081                    if ($local_file === 
false) {
 
 2087                case NET_SFTP_STATUS:
 
 2092                    user_error(
'Expected SSH_FXP_DATA or SSH_FXP_STATUS');
 
 2093                    if ($fclose_check) {
 
 2099            if ($length > 0 && $length <= $offset - 
$start) {
 
 2104        if ($length > 0 && $length <= $offset - 
$start) {
 
 2105            if ($local_file === 
false) {
 
 2106                $content = substr($content, 0, $length);
 
 2108                ftruncate($fp, $length + $res_offset);
 
 2112        if ($fclose_check) {
 
 2121        return isset($content) ? $content : 
true;
 
 2132    function delete(
$path, $recursive = 
true)
 
 2139        if (
$path === 
false) {
 
 2149        if ($this->packet_type != NET_SFTP_STATUS) {
 
 2150            user_error(
'Expected SSH_FXP_STATUS');
 
 2156        if ($status != NET_SFTP_STATUS_OK) {
 
 2192        if (empty($entries)) {
 
 2196        unset($entries[
'.'], $entries[
'..']);
 
 2197        foreach ($entries as 
$filename => $props) {
 
 2198            if (!isset($props[
'type'])) {
 
 2203            if ($props[
'type'] == NET_SFTP_TYPE_DIRECTORY) {
 
 2208                if (!$this->
_send_sftp_packet(NET_SFTP_REMOVE, pack(
'Na*', strlen($temp), $temp))) {
 
 2215                if (
$i >= NET_SFTP_QUEUE_SIZE) {
 
 2231        if (
$i >= NET_SFTP_QUEUE_SIZE) {
 
 2250        if ($this->use_stat_cache) {
 
 2277        return $result === NET_SFTP_TYPE_DIRECTORY;
 
 2293        return $result === NET_SFTP_TYPE_REGULAR;
 
 2309        return $result === NET_SFTP_TYPE_SYMLINK;
 
 2394        if (
$type === 
false) {
 
 2399            case NET_SFTP_TYPE_BLOCK_DEVICE:
 
 2401            case NET_SFTP_TYPE_CHAR_DEVICE:
 
 2403            case NET_SFTP_TYPE_DIRECTORY:
 
 2405            case NET_SFTP_TYPE_FIFO:
 
 2407            case NET_SFTP_TYPE_REGULAR:
 
 2409            case NET_SFTP_TYPE_SYMLINK:
 
 2458        if ($this->use_stat_cache) {
 
 2491        $oldname = $this->_realpath($oldname);
 
 2492        $newname = $this->_realpath($newname);
 
 2493        if ($oldname === 
false || $newname === 
false) {
 
 2498        $packet = pack(
'Na*Na*', strlen($oldname), $oldname, strlen($newname), $newname);
 
 2499        if (!$this->_send_sftp_packet(NET_SFTP_RENAME, $packet)) {
 
 2504        if ($this->packet_type != NET_SFTP_STATUS) {
 
 2505            user_error(
'Expected SSH_FXP_STATUS');
 
 2510        extract(unpack(
'Nstatus', $this->_string_shift(
$response, 4)));
 
 2511        if ($status != NET_SFTP_STATUS_OK) {
 
 2519        $this->_remove_from_stat_cache($oldname);
 
 2520        $this->_remove_from_stat_cache($newname);
 
 2537        extract(unpack(
'Nflags', $this->_string_shift(
$response, 4)));
 
 2539        foreach ($this->attributes as 
$key => $value) {
 
 2540            switch ($flags & 
$key) {
 
 2541                case NET_SFTP_ATTR_SIZE: 
 
 2548                    $attr[
'size'] = hexdec(bin2hex($this->_string_shift(
$response, 8)));
 
 2550                case NET_SFTP_ATTR_UIDGID: 
 
 2551                    $attr+= unpack(
'Nuid/Ngid', $this->_string_shift(
$response, 8));
 
 2553                case NET_SFTP_ATTR_PERMISSIONS: 
 
 2554                    $attr+= unpack(
'Npermissions', $this->_string_shift(
$response, 4));
 
 2557                    $attr+= array(
'mode' => $attr[
'permissions']);
 
 2558                    $fileType = $this->_parseMode($attr[
'permissions']);
 
 2559                    if ($fileType !== 
false) {
 
 2560                        $attr+= array(
'type' => $fileType);
 
 2563                case NET_SFTP_ATTR_ACCESSTIME: 
 
 2564                    $attr+= unpack(
'Natime/Nmtime', $this->_string_shift(
$response, 8));
 
 2566                case NET_SFTP_ATTR_EXTENDED: 
 
 2567                    extract(unpack(
'Ncount', $this->_string_shift(
$response, 4)));
 
 2568                    for (
$i = 0; 
$i < $count; 
$i++) {
 
 2569                        extract(unpack(
'Nlength', $this->_string_shift(
$response, 4)));
 
 2571                        extract(unpack(
'Nlength', $this->_string_shift(
$response, 4)));
 
 2592        switch ($mode & 0170000) {
 
 2596                return NET_SFTP_TYPE_DIRECTORY;
 
 2598                return NET_SFTP_TYPE_REGULAR;
 
 2600                return NET_SFTP_TYPE_SYMLINK;
 
 2604                return NET_SFTP_TYPE_FIFO;
 
 2606                return NET_SFTP_TYPE_CHAR_DEVICE;
 
 2608                return NET_SFTP_TYPE_BLOCK_DEVICE;
 
 2610                return NET_SFTP_TYPE_SOCKET;
 
 2614                return NET_SFTP_TYPE_SPECIAL;
 
 2616                return NET_SFTP_TYPE_UNKNOWN;
 
 2639        if (preg_match(
'#^[^/]([r-][w-][xstST-]){3}#', $longname)) {
 
 2640            switch ($longname[0]) {
 
 2642                    return NET_SFTP_TYPE_REGULAR;
 
 2644                    return NET_SFTP_TYPE_DIRECTORY;
 
 2646                    return NET_SFTP_TYPE_SYMLINK;
 
 2648                    return NET_SFTP_TYPE_SPECIAL;
 
 2669        $packet = $this->request_id !== 
false ?
 
 2673        $start = strtok(microtime(), 
' ') + strtok(
''); 
 
 2674        $result = $this->_send_channel_packet(self::CHANNEL, $packet);
 
 2675        $stop = strtok(microtime(), 
' ') + strtok(
'');
 
 2677        if (defined(
'NET_SFTP_LOGGING')) {
 
 2678            $packet_type = 
'-> ' . $this->packet_types[
$type] .
 
 2679                           ' (' . round($stop - 
$start, 4) . 
's)';
 
 2680            if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
 
 2681                echo 
"<pre>\r\n" . $this->_format_log(array(
$data), array($packet_type)) . 
"\r\n</pre>\r\n";
 
 2685                $this->packet_type_log[] = $packet_type;
 
 2686                if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
 
 2687                    $this->packet_log[] = 
$data;
 
 2710        $this->curTimeout = 
false;
 
 2712        $start = strtok(microtime(), 
' ') + strtok(
''); 
 
 2715        while (strlen($this->packet_buffer) < 4) {
 
 2716            $temp = $this->_get_channel_packet(self::CHANNEL);
 
 2717            if (is_bool($temp)) {
 
 2718                $this->packet_type = 
false;
 
 2719                $this->packet_buffer = 
'';
 
 2722            $this->packet_buffer.= $temp;
 
 2724        extract(unpack(
'Nlength', $this->_string_shift($this->packet_buffer, 4)));
 
 2725        $tempLength = $length;
 
 2726        $tempLength-= strlen($this->packet_buffer);
 
 2729        while ($tempLength > 0) {
 
 2730            $temp = $this->_get_channel_packet(self::CHANNEL);
 
 2731            if (is_bool($temp)) {
 
 2732                $this->packet_type = 
false;
 
 2733                $this->packet_buffer = 
'';
 
 2736            $this->packet_buffer.= $temp;
 
 2737            $tempLength-= strlen($temp);
 
 2740        $stop = strtok(microtime(), 
' ') + strtok(
'');
 
 2742        $this->packet_type = ord($this->_string_shift($this->packet_buffer));
 
 2744        if ($this->request_id !== 
false) {
 
 2745            $this->_string_shift($this->packet_buffer, 4); 
 
 2751        $packet = $this->_string_shift($this->packet_buffer, $length);
 
 2753        if (defined(
'NET_SFTP_LOGGING')) {
 
 2754            $packet_type = 
'<- ' . $this->packet_types[$this->packet_type] .
 
 2755                           ' (' . round($stop - 
$start, 4) . 
's)';
 
 2756            if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
 
 2757                echo 
"<pre>\r\n" . $this->_format_log(array($packet), array($packet_type)) . 
"\r\n</pre>\r\n";
 
 2761                $this->packet_type_log[] = $packet_type;
 
 2762                if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
 
 2763                    $this->packet_log[] = $packet;
 
 2781        if (!defined(
'NET_SFTP_LOGGING')) {
 
 2785        switch (NET_SFTP_LOGGING) {
 
 2786            case NET_SFTP_LOG_COMPLEX:
 
 2787                return $this->_format_log($this->packet_log, $this->packet_type_log);
 
 2791                return $this->packet_type_log;
 
 2803        return $this->sftp_errors;
 
 2814        return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : 
'';
 
 2825        $temp = array(
'version' => $this->version);
 
 2826        if (isset($this->extensions[
'versions'])) {
 
 2827            $temp[
'extensions'] = $this->extensions[
'versions'];
 
 2842        parent::_disconnect($reason);
 
An exception for terminatinating execution or to throw for unit testing.
fileperms($path)
Gets file permissions.
_nlist_helper($dir, $recursive, $relativeDir)
Helper method for nlist.
chown($filename, $uid, $recursive=false)
Changes file or directory owner.
const RESUME
Resumes an upload.
nlist($dir='.', $recursive=false)
Returns a list of files in the given directory.
__construct($host, $port=22, $timeout=10)
Default Constructor.
_parseAttributes(&$response)
Parse Attributes.
_send_sftp_packet($type, $data)
Sends SFTP Packets.
setListOrder()
Defines how nlist() and rawlist() will be sorted - if at all.
_read_put_responses($i)
Reads multiple successive SSH_FXP_WRITE responses.
_stat($filename, $type)
Returns general information about a file or symbolic link.
_parseMode($mode)
Attempt to identify the file type.
clearStatCache()
Clear the stat cache.
const SOURCE_CALLBACK
Reads data from callback: function callback($length) returns string to proceed, null for EOF.
_disconnect($reason)
Disconnect.
stat($filename)
Returns general information about a file.
_delete_recursive($path, &$i)
Recursively deletes directories on the SFTP server.
chdir($dir)
Changes the current directory.
getSupportedVersions()
Get supported SFTP versions.
rawlist($dir='.', $recursive=false)
Returns a detailed list of files in the given directory.
_update_stat_cache($path, $value)
Save files / directories to cache.
touch($filename, $time=null, $atime=null)
Sets access and modification time of file.
_close_handle($handle)
Close handle.
rename($oldname, $newname)
Renames a file or a directory on the SFTP server.
size($filename)
Returns the file size, in bytes, or false, on failure.
mkdir($dir, $mode=-1, $recursive=false)
Creates a directory.
readlink($link)
Return the target of a symbolic link.
chgrp($filename, $gid, $recursive=false)
Changes file or directory group.
getSFTPErrors()
Returns all errors.
_get_stat_cache_prop($path, $prop)
Return a stat properity.
rmdir($dir)
Removes a directory.
is_dir($path)
Tells whether the filename is a directory.
disableStatCache()
Disable the stat cache.
_remove_from_stat_cache($path)
Remove files / directories from cache.
chmod($mode, $filename, $recursive=false)
Set permissions on a file.
_comparator($a, $b)
Compares two rawlist entries using parameters set by setListOrder()
_list($dir, $raw=true)
Reads a list, be it detailed or not, of files in the given directory.
pwd()
Returns the current directory name.
getLastSFTPError()
Returns the last error.
fileowner($path)
Gets file owner.
_parseLongname($longname)
Parse Longname.
is_link($path)
Tells whether the filename is a symbolic link.
filemtime($path)
Gets file modification time.
_get_xstat_cache_prop($path, $prop, $type)
Return a stat or lstat properity.
enableStatCache()
Enable the stat cache.
_logError($response, $status=-1)
Logs errors.
_setstat($filename, $attr, $recursive)
Sets information about a file.
_setstat_recursive($path, $attr, &$i)
Recursively sets information on directories on the SFTP server.
_get_lstat_cache_prop($path, $prop)
Return an lstat properity.
truncate($filename, $new_size)
Truncates a file to a given length.
const SOURCE_STRING
Reads data from a string.
const SOURCE_LOCAL_FILE
#+ @access public
_mkdir_helper($dir, $attr)
Helper function for directory creation.
_realpath($path)
Canonicalize the Server-Side Path Name.
const CHANNEL
SFTP channel constant.
filegroup($path)
Gets file group.
filetype($path)
Gets file type.
is_file($path)
Tells whether the filename is a regular file.
_query_stat_cache($path)
Checks cache for path.
getSFTPLog()
Returns a log of the packets that have been sent and received.
symlink($target, $link)
Create a symlink.
fileatime($path)
Gets last access time of file.
filesize($path)
Gets file size.
lstat($filename)
Returns general information about a file or symbolic link.
const RESUME_START
Append a local file to an already existing remote file.
put($remote_file, $data, $mode=self::SOURCE_STRING, $start=-1, $local_start=-1, $progressCallback=null)
Uploads a file to the SFTP server.
_get_sftp_packet()
Receives SFTP Packets.
file_exists($path)
Checks whether a file or directory exists.
_get_channel_packet($client_channel, $skip_extended=false)
Gets channel data.
_string_shift(&$string, $index=1)
String Shift.
_define_array()
Define Array.
_send_binary_packet($data, $logged=null)
Sends Binary Packets.
if(array_key_exists('yes', $_REQUEST)) $attributes
Pure-PHP implementations of SFTP.
Pure-PHP implementation of SSHv2.