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;
1852 case $mode & self::SOURCE_CALLBACK:
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):
1863 case $mode & self::SOURCE_LOCAL_FILE:
1865 user_error(
"$data is not a valid file");
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) {
2493 if ($oldname ===
false || $newname ===
false) {
2498 $packet = pack(
'Na*Na*', strlen($oldname), $oldname, strlen($newname), $newname);
2504 if ($this->packet_type != NET_SFTP_STATUS) {
2505 user_error(
'Expected SSH_FXP_STATUS');
2511 if ($status != NET_SFTP_STATUS_OK) {
2539 foreach ($this->attributes as
$key => $value) {
2540 switch ($flags &
$key) {
2541 case NET_SFTP_ATTR_SIZE:
2550 case NET_SFTP_ATTR_UIDGID:
2553 case NET_SFTP_ATTR_PERMISSIONS:
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:
2566 case NET_SFTP_ATTR_EXTENDED:
2568 for (
$i = 0;
$i < $count;
$i++) {
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(
'');
2675 $stop = strtok(microtime(),
' ') + strtok(
'');
2677 if (defined(
'NET_SFTP_LOGGING')) {
2679 ' (' . round($stop -
$start, 4) .
's)';
2680 if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
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) {
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) {
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) {
2751 $packet = $this->
_string_shift($this->packet_buffer, $length);
2753 if (defined(
'NET_SFTP_LOGGING')) {
2755 ' (' . round($stop -
$start, 4) .
's)';
2756 if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
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);
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);
clearStatCache()
Clear the stat cache.
touch($filename, $time=null, $atime=null)
Sets access and modification time of file.
_get_xstat_cache_prop($path, $prop, $type)
Return a stat or lstat properity.
readlink($link)
Return the target of a symbolic link.
_parseLongname($longname)
Parse Longname.
rawlist($dir='.', $recursive=false)
Returns a detailed list of files in the given directory.
_stat($filename, $type)
Returns general information about a file or symbolic link.
_realpath($path)
Canonicalize the Server-Side Path Name.
_get_sftp_packet()
Receives SFTP Packets.
nlist($dir='.', $recursive=false)
Returns a list of files in the given directory.
_logError($response, $status=-1)
Logs errors.
filesize($path)
Gets file size.
setListOrder()
Defines how nlist() and rawlist() will be sorted - if at all.
_get_lstat_cache_prop($path, $prop)
Return an lstat properity.
_define_array()
Define Array.
getSupportedVersions()
Get supported SFTP versions.
_get_stat_cache_prop($path, $prop)
Return a stat properity.
_query_stat_cache($path)
Checks cache for path.
_format_log($message_log, $message_number_log)
Formats a log for printing.
_comparator($a, $b)
Compares two rawlist entries using parameters set by setListOrder()
disableStatCache()
Disable the stat cache.
filemtime($path)
Gets file modification time.
__construct($host, $port=22, $timeout=10)
Default Constructor.
_parseAttributes(&$response)
Parse Attributes.
chdir($dir)
Changes the current directory.
_remove_from_stat_cache($path)
Remove files / directories from cache.
_send_sftp_packet($type, $data)
Sends SFTP Packets.
truncate($filename, $new_size)
Truncates a file to a given length.
getLastSFTPError()
Returns the last error.
const SOURCE_STRING
Reads data from a string.
_disconnect($reason)
Disconnect.
symlink($target, $link)
Create a symlink.
_setstat($filename, $attr, $recursive)
Sets information about a file.
stat($filename)
Returns general information about a file.
size($filename)
Returns the file size, in bytes, or false, on failure.
is_file($path)
Tells whether the filename is a regular file.
const RESUME
Resumes an upload.
getSFTPErrors()
Returns all errors.
Pure-PHP implementation of SSHv2.
rmdir($dir)
Removes a directory.
filegroup($path)
Gets file group.
_delete_recursive($path, &$i)
Recursively deletes directories on the SFTP server.
_update_stat_cache($path, $value)
Save files / directories to cache.
_parseMode($mode)
Attempt to identify the file type.
const CHANNEL
SFTP channel constant.
enableStatCache()
Enable the stat cache.
is_link($path)
Tells whether the filename is a symbolic link.
_close_handle($handle)
Close handle.
if(array_key_exists('yes', $_REQUEST)) $attributes
_setstat_recursive($path, $attr, &$i)
Recursively sets information on directories on the SFTP server.
is_dir($path)
Tells whether the filename is a directory.
_nlist_helper($dir, $recursive, $relativeDir)
Helper method for nlist.
_string_shift(&$string, $index=1)
String Shift.
_send_binary_packet($data, $logged=null)
Sends Binary Packets.
chown($filename, $uid, $recursive=false)
Changes file or directory owner.
mkdir($dir, $mode=-1, $recursive=false)
Creates a directory.
put($remote_file, $data, $mode=self::SOURCE_STRING, $start=-1, $local_start=-1, $progressCallback=null)
Uploads a file to the SFTP server.
chgrp($filename, $gid, $recursive=false)
Changes file or directory group.
_mkdir_helper($dir, $attr)
Helper function for directory creation.
pwd()
Returns the current directory name.
_list($dir, $raw=true)
Reads a list, be it detailed or not, of files in the given directory.
chmod($mode, $filename, $recursive=false)
Set permissions on a file.
file_exists($path)
Checks whether a file or directory exists.
_get_channel_packet($client_channel, $skip_extended=false)
Gets channel data.
fileowner($path)
Gets file owner.
const SOURCE_LOCAL_FILE
#+ public
const RESUME_START
Append a local file to an already existing remote file.
_send_channel_packet($client_channel, $data)
Sends channel data.
_read_put_responses($i)
Reads multiple successive SSH_FXP_WRITE responses.
lstat($filename)
Returns general information about a file or symbolic link.
getSFTPLog()
Returns a log of the packets that have been sent and received.
fileatime($path)
Gets last access time of file.
const SOURCE_CALLBACK
Reads data from callback: function callback($length) returns string to proceed, null for EOF...
rename($oldname, $newname)
Renames a file or a directory on the SFTP server.
filetype($path)
Gets file type.
fileperms($path)
Gets file permissions.