Lines Matching +full:leave +full:- +full:group -(+path:inc +path:lang) -(+path:lib +path:plugins +path:lang) -(+path:lib +path:tpl +path:dokuwiki +path:lang)

4  * Pure-PHP implementation of SFTP.
18 * if (!$sftp->login('username', 'password')) {
22 * echo $sftp->pwd() . "\r\n";
23 * $sftp->put('filename.ext', 'hello, world!');
24 * print_r($sftp->nlist());
30 * @license http://www.opensource.org/licenses/mit-license.html MIT License
40 * Pure-PHP implementations of SFTP.
122 * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
133 * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
139 private $packet_type = -1;
207 * Real-time log file pointer
210 * @var resource|closed-resource
215 * Real-time log file size
223 * Real-time log file wrap boolean
324 * 256 * 1024 bytes (SFTP_MAX_MSG_LENGTH from OpenSSH's sftp-common.h)
363 $this->max_sftp_packet = 1 << 15;
430 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
431 // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why
449 // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers
450 // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
451 // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
452 // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
453 (PHP_INT_SIZE == 4 ? (-1 << 31) : 0x80000000) => 'NET_SFTP_ATTR_EXTENDED'
455 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
457 // the array for that $this->open5_flags and similarly alter the constant names.
468 // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3
491 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2
500 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2
531 if (!($this->bitmap & SSH2::MASK_LOGIN)) {
535 if ($this->pwd === false) {
536 return $this->init_sftp_connection();
550 $response = $this->open_channel(self::CHANNEL, true);
551 if ($response === true && $this->isTimeout()) {
558 $this->server_channels[self::CHANNEL],
563 $this->send_binary_packet($packet);
565 $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
567 $response = $this->get_channel_packet(self::CHANNEL, true);
570 $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
571 "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n" .
572 "exec sftp-server";
573 // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does
578 $this->server_channels[self::CHANNEL],
583 $this->send_binary_packet($packet);
585 $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
587 $response = $this->get_channel_packet(self::CHANNEL, true);
591 } elseif ($response === true && $this->isTimeout()) {
595 $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA;
596 $this->send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3");
598 $response = $this->get_sftp_packet();
599 if ($this->packet_type != NET_SFTP_VERSION) {
601 . 'Got packet type: ' . $this->packet_type);
604 $this->use_request_id = true;
606 list($this->defaultVersion) = Strings::unpackSSH2('N', $response);
609 $this->extensions[$key] = $value;
612 $this->partial_init = true;
624 if (!$this->partial_init && !$this->partial_init_sftp_connection()) {
630 <http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.1> states the following:
639 <http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.5> states the following;
641 "If the server did not send the "versions" extension, or the version-from-list was not included, the
647 v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed
648 in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib3\Net\SFTP would do is close the
651 $this->version = $this->defaultVersion;
652 if (isset($this->extensions['versions']) && (!$this->preferredVersion || $this->preferredVersion != $this->version)) {
653 $versions = explode(',', $this->extensions['versions']);
655 if ($this->preferredVersion) {
656 $supported = array_diff($supported, [$this->preferredVersion]);
657 array_unshift($supported, $this->preferredVersion);
661 if ($ver === $this->version) {
664 $this->version = (int) $ver;
665 $packet = Strings::packSSH2('ss', 'version-select', "$ver");
666 $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet);
667 $response = $this->get_sftp_packet();
668 if ($this->packet_type != NET_SFTP_STATUS) {
670 . 'Got packet type: ' . $this->packet_type);
674 $this->logError($response, $status);
686 not in the official SFTPv3 specs) and 'newline@vandyke.com' / 'newline' are likely not drop-in substitutes for
691 if (isset($this->extensions['newline@vandyke.com'])) {
692 $this->extensions['newline'] = $this->extensions['newline@vandyke.com'];
693 unset($this->extensions['newline@vandyke.com']);
696 if ($this->version < 2 || $this->version > 6) {
700 $this->pwd = true;
702 $this->pwd = $this->realpath('.');
704 if (!$this->canonicalize_paths) {
707 $this->canonicalize_paths = false;
708 $this->reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST);
711 $this->update_stat_cache($this->pwd, []);
722 $this->use_stat_cache = false;
731 $this->use_stat_cache = true;
740 $this->stat_cache = [];
749 $this->canonicalize_paths = true;
755 * If this is enabled then $sftp->pwd() will not return the canonicalized absolute path
760 $this->canonicalize_paths = false;
769 $this->allow_arbitrary_length_packets = true;
778 $this->allow_arbitrary_length_packets = false;
788 if (!$this->precheck()) {
792 return $this->pwd;
801 private function logError($response, $status = -1)
803 if ($status == -1) {
809 if ($this->version > 2) {
811 $this->sftp_errors[] = "$error: $message";
813 $this->sftp_errors[] = $error;
818 * Canonicalize the Server-Side Path Name
823 * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is.
833 if ($this->precheck() === false) {
837 if (!$this->canonicalize_paths) {
838 if ($this->pwd === true) {
842 $path = $this->pwd . '/' . $path;
866 if ($this->pwd === true) {
867 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
868 $this->send_sftp_packet(NET_SFTP_REALPATH, Strings::packSSH2('s', $path));
870 $response = $this->get_sftp_packet();
871 switch ($this->packet_type) {
879 $this->logError($response);
883 . 'Got packet type: ' . $this->packet_type);
888 $path = $this->pwd . '/' . $path;
900 // fall-through
920 if (!$this->precheck()) {
928 } elseif ($dir[strlen($dir) - 1] != '/') {
932 $dir = $this->realpath($dir);
935 if ($this->use_stat_cache && is_array($this->query_stat_cache($dir))) {
936 $this->pwd = $dir;
945 $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir));
948 $response = $this->get_sftp_packet();
949 switch ($this->packet_type) {
954 $this->logError($response);
958 'Got packet type: ' . $this->packet_type);
961 if (!$this->close_handle($handle)) {
965 $this->update_stat_cache($dir, []);
967 $this->pwd = $dir;
980 return $this->nlist_helper($dir, $recursive, '');
993 $files = $this->readlist($dir, false);
1011 if (is_array($this->query_stat_cache($this->realpath($dir . '/' . $value)))) {
1012 $temp = $this->nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/');
1032 $files = $this->readlist($dir, true);
1053 if ($this->use_stat_cache) {
1054 $is_directory = is_array($this->query_stat_cache($this->realpath($dir . '/' . $key)));
1056 $stat = $this->lstat($dir . '/' . $key);
1063 $files[$key] = $this->rawlist($dir . '/' . $key, true);
1064 $depth--;
1083 if (!$this->precheck()) {
1087 $dir = $this->realpath($dir . '/');
1092 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2
1093 $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir));
1095 $response = $this->get_sftp_packet();
1096 switch ($this->packet_type) {
1098 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2
1100 // represent the length of the string and leave it at that
1106 $this->logError($response, $status);
1110 . 'Got packet type: ' . $this->packet_type);
1113 $this->update_stat_cache($dir, []);
1117 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2
1120 $this->send_sftp_packet(NET_SFTP_READDIR, Strings::packSSH2('s', $handle));
1122 $response = $this->get_sftp_packet();
1123 switch ($this->packet_type) {
1128 // SFTPv4 "removed the long filename from the names structure-- it can now be
1130 if ($this->version < 4) {
1133 $attributes = $this->parseAttributes($response);
1134 if (!isset($attributes['type']) && $this->version < 4) {
1135 $fileType = $this->parseLongname($longname);
1143 $this->update_stat_cache($dir . '/' . $shortname, []);
1146 $temp = $this->realpath($dir . '/..') . '/.';
1150 $this->update_stat_cache($temp, (object) ['lstat' => $attributes]);
1152 // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the
1159 $this->logError($response, $status);
1165 . 'Got packet type: ' . $this->packet_type);
1169 if (!$this->close_handle($handle)) {
1173 if (count($this->sortOptions)) {
1196 return $a['filename'] === '.' ? -1 : 1;
1201 return $a['filename'] === '..' ? -1 : 1;
1207 return -1;
1213 foreach ($this->sortOptions as $sort => $order) {
1216 return -1;
1227 return $order === SORT_DESC ? -$result : $result;
1233 // fall-through
1238 return $order === SORT_ASC ? $a[$sort] - $b[$sort] : $b[$sort] - $a[$sort];
1244 * Defines how nlist() and rawlist() will be sorted - if at all.
1254 * $sftp->setListOrder('filename', SORT_ASC);
1255 * $sftp->setListOrder('size', SORT_DESC, 'filename', SORT_ASC);
1256 * $sftp->setListOrder(true);
1258 * $sftp->setListOrder();
1265 $this->sortOptions = [];
1271 $this->sortOptions[$args[$i]] = $args[$i + 1];
1273 if (!count($this->sortOptions)) {
1274 $this->sortOptions = ['bogus' => true];
1286 if ($this->use_stat_cache === false) {
1293 $temp = &$this->stat_cache;
1294 $max = count($dirs) - 1;
1307 if (!isset($value->stat) && isset($temp[$dir]->stat)) {
1308 $value->stat = $temp[$dir]->stat;
1310 if (!isset($value->lstat) && isset($temp[$dir]->lstat)) {
1311 $value->lstat = $temp[$dir]->lstat;
1331 $temp = &$this->stat_cache;
1332 $max = count($dirs) - 1;
1360 $temp = &$this->stat_cache;
1383 if (!$this->precheck()) {
1387 $filename = $this->realpath($filename);
1392 if ($this->use_stat_cache) {
1393 $result = $this->query_stat_cache($filename);
1394 if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) {
1395 return $result['.']->stat;
1397 if (is_object($result) && isset($result->stat)) {
1398 return $result->stat;
1402 $stat = $this->stat_helper($filename, NET_SFTP_STAT);
1404 $this->remove_from_stat_cache($filename);
1411 $this->update_stat_cache($filename, (object) ['stat' => $stat]);
1415 $pwd = $this->pwd;
1416 $stat['type'] = $this->chdir($filename) ?
1419 $this->pwd = $pwd;
1424 $this->update_stat_cache($filename, (object) ['stat' => $stat]);
1439 if (!$this->precheck()) {
1443 $filename = $this->realpath($filename);
1448 if ($this->use_stat_cache) {
1449 $result = $this->query_stat_cache($filename);
1450 if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) {
1451 return $result['.']->lstat;
1453 if (is_object($result) && isset($result->lstat)) {
1454 return $result->lstat;
1458 $lstat = $this->stat_helper($filename, NET_SFTP_LSTAT);
1460 $this->remove_from_stat_cache($filename);
1467 $this->update_stat_cache($filename, (object) ['lstat' => $lstat]);
1471 $stat = $this->stat_helper($filename, NET_SFTP_STAT);
1475 $this->update_stat_cache($filename, (object) ['lstat' => $lstat]);
1479 $pwd = $this->pwd;
1480 $lstat['type'] = $this->chdir($filename) ?
1483 $this->pwd = $pwd;
1488 $this->update_stat_cache($filename, (object) ['lstat' => $lstat]);
1506 // SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
1508 $this->send_sftp_packet($type, $packet);
1510 $response = $this->get_sftp_packet();
1511 switch ($this->packet_type) {
1513 return $this->parseAttributes($response);
1515 $this->logError($response);
1520 . 'Got packet type: ' . $this->packet_type);
1534 return $this->setstat($filename, $attr, false);
1550 if (!$this->precheck()) {
1554 $filename = $this->realpath($filename);
1566 $attr = $this->version < 4 ?
1571 $packet .= $this->version >= 5 ?
1576 $this->send_sftp_packet(NET_SFTP_OPEN, $packet);
1578 $response = $this->get_sftp_packet();
1579 switch ($this->packet_type) {
1581 return $this->close_handle(substr($response, 4));
1583 $this->logError($response);
1587 . 'Got packet type: ' . $this->packet_type);
1590 return $this->setstat($filename, $attr, false);
1598 * `$sftp->getSupportedVersions()['version']` will return the specific version
1611 quoting <https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.5>,
1614 implementation at the client or server, the use of UTF-8 strings has
1627 $attr = $this->version < 4 ?
1628 // quoting <http://www.kernel.org/doc/man-pages/online/pages/man2/chown.2.html>,
1629 // "if the owner or group is specified as -1, then that ID is not changed"
1630 pack('N3', NET_SFTP_ATTR_UIDGID, $uid, -1) :
1631 // quoting <https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.5>,
1632 // "If either the owner or group field is zero length, the field should be
1637 return $this->setstat($filename, $attr, $recursive);
1641 * Changes file or directory group
1645 * `$sftp->getSupportedVersions()['version']` will return the specific version
1657 $attr = $this->version < 4 ?
1658 pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid) :
1661 return $this->setstat($filename, $attr, $recursive);
1685 if (!$this->setstat($filename, $attr, $recursive)) {
1692 $filename = $this->realpath($filename);
1695 // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
1697 $this->send_sftp_packet(NET_SFTP_STAT, $packet);
1699 $response = $this->get_sftp_packet();
1700 switch ($this->packet_type) {
1702 $attrs = $this->parseAttributes($response);
1705 $this->logError($response);
1710 . 'Got packet type: ' . $this->packet_type);
1724 if (!$this->precheck()) {
1728 $filename = $this->realpath($filename);
1733 $this->remove_from_stat_cache($filename);
1737 $result = $this->setstat_recursive($filename, $attr, $i);
1738 $this->read_put_responses($i);
1743 $packet .= $this->version >= 4 ?
1746 $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet);
1753 -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6
1755 $response = $this->get_sftp_packet();
1756 if ($this->packet_type != NET_SFTP_STATUS) {
1758 . 'Got packet type: ' . $this->packet_type);
1763 $this->logError($response, $status);
1782 if (!$this->read_put_responses($i)) {
1786 $entries = $this->readlist($path, true);
1789 return $this->setstat($path, $attr, false);
1806 if (!$this->setstat_recursive($temp, $attr, $i)) {
1811 $packet .= $this->version >= 4 ?
1814 $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet);
1819 if (!$this->read_put_responses($i)) {
1828 $packet .= $this->version >= 4 ?
1831 $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet);
1836 if (!$this->read_put_responses($i)) {
1854 if (!$this->precheck()) {
1858 $link = $this->realpath($link);
1860 $this->send_sftp_packet(NET_SFTP_READLINK, Strings::packSSH2('s', $link));
1862 $response = $this->get_sftp_packet();
1863 switch ($this->packet_type) {
1867 $this->logError($response);
1871 . 'Got packet type: ' . $this->packet_type);
1897 if (!$this->precheck()) {
1901 //$target = $this->realpath($target);
1902 $link = $this->realpath($link);
1904 /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-12.1 :
1911 if ($this->version == 6) {
1920 When OpenSSH's sftp-server was implemented, the order of the arguments
1930 $packet = substr($this->server_identifier, 0, 15) == 'SSH-2.0-OpenSSH' ?
1934 $this->send_sftp_packet($type, $packet);
1936 $response = $this->get_sftp_packet();
1937 if ($this->packet_type != NET_SFTP_STATUS) {
1939 . 'Got packet type: ' . $this->packet_type);
1944 $this->logError($response, $status);
1959 public function mkdir($dir, $mode = -1, $recursive = false)
1961 if (!$this->precheck()) {
1965 $dir = $this->realpath($dir);
1976 $result = $this->mkdir_helper($temp, $mode);
1981 return $this->mkdir_helper($dir, $mode);
1994 $this->send_sftp_packet(NET_SFTP_MKDIR, Strings::packSSH2('s', $dir) . "\0\0\0\0");
1996 $response = $this->get_sftp_packet();
1997 if ($this->packet_type != NET_SFTP_STATUS) {
1999 . 'Got packet type: ' . $this->packet_type);
2004 $this->logError($response, $status);
2008 if ($mode !== -1) {
2009 $this->chmod($mode, $dir);
2024 if (!$this->precheck()) {
2028 $dir = $this->realpath($dir);
2033 $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $dir));
2035 $response = $this->get_sftp_packet();
2036 if ($this->packet_type != NET_SFTP_STATUS) {
2038 . 'Got packet type: ' . $this->packet_type);
2044 $this->logError($response, $status);
2048 $this->remove_from_stat_cache($dir);
2052 //$this->update_stat_cache($dir, false);
2068 * Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number
2076 * $mode can take an additional two parameters - self::RESUME and self::RESUME_START. These are bitwise AND'd with
2087 * when they're non-negative. ie. $start could let you write at the end of a file (like self::RESUME) or in the middle
2093 * {@internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib3\Net\SFTP::setMode().}
2106 public function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null)
2108 if (!$this->precheck()) {
2112 $remote_file = $this->realpath($remote_file);
2117 $this->remove_from_stat_cache($remote_file);
2119 if ($this->version >= 5) {
2132 $stat = $this->stat($remote_file);
2136 if ($this->version >= 5) {
2143 $this->remove_from_stat_cache($remote_file);
2146 $packet .= $this->version >= 5 ?
2149 $this->send_sftp_packet(NET_SFTP_OPEN, $packet);
2151 $response = $this->get_sftp_packet();
2152 switch ($this->packet_type) {
2157 $this->logError($response);
2161 . 'Got packet type: ' . $this->packet_type);
2164 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
2201 $size -= $local_start;
2204 $size -= $offset;
2215 $sftp_packet_size = $this->max_sftp_packet;
2217 $sftp_packet_size -= strlen($handle) + 25;
2235 $this->send_sftp_packet(NET_SFTP_WRITE, $packet, $j);
2250 if (!$this->read_put_responses($i)) {
2258 $result = $this->close_handle($handle);
2260 if (!$this->read_put_responses($i)) {
2264 $this->close_handle($handle);
2273 if ($this->preserveTime) {
2275 $attr = $this->version < 4 ?
2278 if (!$this->setstat($remote_file, $attr, false)) {
2299 while ($i--) {
2300 $response = $this->get_sftp_packet();
2301 if ($this->packet_type != NET_SFTP_STATUS) {
2303 . 'Got packet type: ' . $this->packet_type);
2308 $this->logError($response, $status);
2325 $this->send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle));
2328 // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
2329 $response = $this->get_sftp_packet();
2330 if ($this->packet_type != NET_SFTP_STATUS) {
2332 . 'Got packet type: ' . $this->packet_type);
2337 $this->logError($response, $status);
2361 public function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null)
2363 if (!$this->precheck()) {
2367 $remote_file = $this->realpath($remote_file);
2373 $packet .= $this->version >= 5 ?
2376 $this->send_sftp_packet(NET_SFTP_OPEN, $packet);
2378 $response = $this->get_sftp_packet();
2379 switch ($this->packet_type) {
2384 $this->logError($response);
2388 . 'Got packet type: ' . $this->packet_type);
2417 $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
2421 $this->send_sftp_packet(NET_SFTP_READ, $packet, $i);
2437 $packets_sent = $i - 1;
2441 $i--;
2444 $this->get_sftp_packet($packets_sent - $i);
2447 $response = $this->get_sftp_packet($packets_sent - $i);
2450 switch ($this->packet_type) {
2468 $this->logError($response);
2475 if ($this->channel_close) {
2476 $this->partial_init = false;
2477 $this->init_sftp_connection();
2481 . 'Got packet type: ' . $this->packet_type);
2495 if ($this->preserveTime) {
2496 $stat = $this->stat($remote_file);
2501 if (!$this->close_handle($handle)) {
2519 if (!$this->precheck()) {
2532 $path = $this->realpath($path);
2537 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
2538 $this->send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path));
2540 $response = $this->get_sftp_packet();
2541 if ($this->packet_type != NET_SFTP_STATUS) {
2543 . 'Got packet type: ' . $this->packet_type);
2549 $this->logError($response, $status);
2555 $result = $this->delete_recursive($path, $i);
2556 $this->read_put_responses($i);
2560 $this->remove_from_stat_cache($path);
2576 if (!$this->read_put_responses($i)) {
2580 $entries = $this->readlist($path, true);
2601 if (!$this->delete_recursive($temp, $i)) {
2605 $this->send_sftp_packet(NET_SFTP_REMOVE, Strings::packSSH2('s', $temp));
2606 $this->remove_from_stat_cache($temp);
2611 if (!$this->read_put_responses($i)) {
2619 $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $path));
2620 $this->remove_from_stat_cache($path);
2625 if (!$this->read_put_responses($i)) {
2642 if ($this->use_stat_cache) {
2643 if (!$this->precheck()) {
2647 $path = $this->realpath($path);
2649 $result = $this->query_stat_cache($path);
2657 return $this->stat($path) !== false;
2668 $result = $this->get_stat_cache_prop($path, 'type');
2683 $result = $this->get_stat_cache_prop($path, 'type');
2698 $result = $this->get_lstat_cache_prop($path, 'type');
2713 if (!$this->precheck()) {
2717 $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_READ, 0);
2718 $this->send_sftp_packet(NET_SFTP_OPEN, $packet);
2720 $response = $this->get_sftp_packet();
2721 switch ($this->packet_type) {
2728 . 'Got packet type: ' . $this->packet_type);
2740 if (!$this->precheck()) {
2744 $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_WRITE, 0);
2745 $this->send_sftp_packet(NET_SFTP_OPEN, $packet);
2747 $response = $this->get_sftp_packet();
2748 switch ($this->packet_type) {
2755 . 'Got packet type: ' . $this->packet_type);
2769 return $this->is_writable($path);
2780 return $this->get_stat_cache_prop($path, 'atime');
2791 return $this->get_stat_cache_prop($path, 'mtime');
2802 return $this->get_stat_cache_prop($path, 'mode');
2813 return $this->get_stat_cache_prop($path, 'uid');
2817 * Gets file group
2824 return $this->get_stat_cache_prop($path, 'gid');
2841 $file->size;
2855 return !$recursive || $this->filetype($path) != 'dir' ?
2856 $this->get_stat_cache_prop($path, 'size') :
2857 self::recursiveFilesize($this->rawlist($path, true));
2868 $type = $this->get_stat_cache_prop($path, 'type');
2902 return $this->get_xstat_cache_prop($path, $prop, 'stat');
2916 return $this->get_xstat_cache_prop($path, $prop, 'lstat');
2931 if (!$this->precheck()) {
2935 if ($this->use_stat_cache) {
2936 $path = $this->realpath($path);
2938 $result = $this->query_stat_cache($path);
2940 if (is_object($result) && isset($result->$type)) {
2941 return $result->{$type}[$prop];
2945 $result = $this->$type($path);
2966 if (!$this->precheck()) {
2970 $oldname = $this->realpath($oldname);
2971 $newname = $this->realpath($newname);
2976 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
2978 if ($this->version >= 5) {
2979 /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-6.5 ,
2990 $this->send_sftp_packet(NET_SFTP_RENAME, $packet);
2992 $response = $this->get_sftp_packet();
2993 if ($this->packet_type != NET_SFTP_STATUS) {
2995 . 'Got packet type: ' . $this->packet_type);
3001 $this->logError($response, $status);
3007 //$this->update_stat_cache($newname, $this->query_stat_cache($oldname));
3008 $this->remove_from_stat_cache($oldname);
3009 $this->remove_from_stat_cache($newname);
3017 * See '7.7. Times' of draft-ietf-secsh-filexfer-13 for more info.
3029 list($attr[$key . '-nseconds']) = Strings::unpackSSH2('N', $response);
3037 * See '7. File Attributes' of draft-ietf-secsh-filexfer-13 for more info.
3044 if ($this->version >= 4) {
3053 if ($this->version > 3) {
3062 if ($this->version < 4) {
3067 if ($this->version < 5) {
3077 if ($this->version < 6) {
3083 // The size attribute is defined as an unsigned 64-bit integer.
3084 // The following will use floats on 32-bit platforms, if necessary.
3096 $fileType = $this->parseMode($attr['mode']);
3097 if ($this->version < 4 && $fileType !== false) {
3102 if ($this->version >= 4) {
3103 $attr += $this->parseTime('atime', $flags, $response);
3109 $attr += $this->parseTime('createtime', $flags, $response);
3112 $attr += $this->parseTime('mtime', $flags, $response);
3116 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-04#section-5.7
3124 list($attr['owner'], $attr['$group']) = Strings::unpackSSH2('ss', $response);
3129 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-5.8
3136 // $attr['attrib-bits'] and $attr['attrib-bits-valid']
3137 // eg. - instead of _
3140 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4
3143 list($attr['allocation-size']) = Strings::unpackSSH2('Q', $response);
3146 // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10
3150 // the above should be $attr['text-hint']
3153 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.11
3154 list($attr['mime-type']) = Strings::unpackSSH2('s', $response);
3157 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12
3158 list($attr['link-count']) = Strings::unpackSSH2('N', $response);
3161 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13
3162 list($attr['untranslated-name']) = Strings::unpackSSH2('s', $response);
3167 $attr += $this->parseTime('ctime', $flags, $response);
3190 // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12
3193 case 0000000: // no file type specified - figure out the file type using alternative means
3202 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2
3225 * SFTPv3-specific longname field of the SSH_FXP_NAME packet. That's what this function does.
3227 * {@link http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 SFTPv4 type constants}.
3238 if (preg_match('#^[^/]([r-][w-][xstST-]){3}#', $longname)) {
3240 case '-':
3257 * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.
3270 $this->curTimeout = $this->timeout;
3272 $packet = $this->use_request_id ?
3277 $this->send_channel_packet(self::CHANNEL, $packet);
3281 $packet_type = '-> ' . self::$packet_types[$type] .
3282 ' (' . round($stop - $start, 4) . 's)';
3283 $this->append_log($packet_type, $data);
3288 * Resets a connection for re-use
3295 $this->use_request_id = false;
3296 $this->pwd = false;
3297 $this->requestBuffer = [];
3298 $this->partial_init = false;
3304 * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.
3315 $this->channel_close = false;
3317 if (isset($request_id) && isset($this->requestBuffer[$request_id])) {
3318 $this->packet_type = $this->requestBuffer[$request_id]['packet_type'];
3319 $temp = $this->requestBuffer[$request_id]['packet'];
3320 unset($this->requestBuffer[$request_id]);
3326 $this->curTimeout = $this->timeout;
3331 while (strlen($this->packet_buffer) < 4) {
3332 $temp = $this->get_channel_packet(self::CHANNEL, true);
3334 if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) {
3335 $this->channel_close = true;
3337 $this->packet_type = false;
3338 $this->packet_buffer = '';
3341 $this->packet_buffer .= $temp;
3343 if (strlen($this->packet_buffer) < 4) {
3346 extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4)));
3350 $tempLength -= strlen($this->packet_buffer);
3352 // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h
3353 if (!$this->allow_arbitrary_length_packets && !$this->use_request_id && $tempLength > 256 * 1024) {
3359 $temp = $this->get_channel_packet(self::CHANNEL, true);
3361 if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) {
3362 $this->channel_close = true;
3364 $this->packet_type = false;
3365 $this->packet_buffer = '';
3368 $this->packet_buffer .= $temp;
3369 $tempLength -= strlen($temp);
3374 $this->packet_type = ord(Strings::shift($this->packet_buffer));
3376 if ($this->use_request_id) {
3377 extract(unpack('Npacket_id', Strings::shift($this->packet_buffer, 4))); // remove the request id
3378 $length -= 5; // account for the request id and the packet type
3380 $length -= 1; // account for the packet type
3383 $packet = Strings::shift($this->packet_buffer, $length);
3386 $packet_type = '<- ' . self::$packet_types[$this->packet_type] .
3387 ' (' . round($stop - $start, 4) . 's)';
3388 $this->append_log($packet_type, $packet);
3391 if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) {
3392 $this->requestBuffer[$packet_id] = [
3393 'packet_type' => $this->packet_type,
3396 return $this->get_sftp_packet($request_id);
3412 $this->append_log_helper(
3416 $this->packet_type_log,
3417 $this->packet_log,
3418 $this->log_size,
3419 $this->realtime_log_file,
3420 $this->realtime_log_wrap,
3421 $this->realtime_log_size
3440 return $this->format_log($this->packet_log, $this->packet_type_log);
3444 return $this->packet_type_log;
3455 return $this->sftp_errors;
3465 return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : '';
3475 if (!($this->bitmap & SSH2::MASK_LOGIN)) {
3479 if (!$this->partial_init) {
3480 $this->partial_init_sftp_connection();
3483 $temp = ['version' => $this->defaultVersion];
3484 if (isset($this->extensions['versions'])) {
3485 $temp['extensions'] = $this->extensions['versions'];
3497 if (!$this->precheck()) {
3501 return $this->version;
3515 $this->preferredVersion = $version;
3526 $this->pwd = false;
3536 $this->preserveTime = true;
3545 $this->preserveTime = false;