Edit File by line
/home/barbar84/www/wp-conte.../plugins/worker/src/PHPSecLi.../Net
File: SFTP.php
return false;
[1500] Fix | Delete
}
[1501] Fix | Delete
[1502] Fix | Delete
$this->_remove_from_stat_cache($filename);
[1503] Fix | Delete
[1504] Fix | Delete
if ($recursive) {
[1505] Fix | Delete
$i = 0;
[1506] Fix | Delete
$result = $this->_setstat_recursive($filename, $attr, $i);
[1507] Fix | Delete
$this->_read_put_responses($i);
[1508] Fix | Delete
[1509] Fix | Delete
return $result;
[1510] Fix | Delete
}
[1511] Fix | Delete
[1512] Fix | Delete
// SFTPv4+ has an additional byte field - type - that would need to be sent, as well. setting it to
[1513] Fix | Delete
// SSH_FILEXFER_TYPE_UNKNOWN might work. if not, we'd have to do an SSH_FXP_STAT before doing an SSH_FXP_SETSTAT.
[1514] Fix | Delete
if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($filename), $filename, $attr))) {
[1515] Fix | Delete
return false;
[1516] Fix | Delete
}
[1517] Fix | Delete
[1518] Fix | Delete
/*
[1519] Fix | Delete
"Because some systems must use separate system calls to set various attributes, it is possible that a failure
[1520] Fix | Delete
response will be returned, but yet some of the attributes may be have been successfully modified. If possible,
[1521] Fix | Delete
servers SHOULD avoid this situation; however, clients MUST be aware that this is possible."
[1522] Fix | Delete
[1523] Fix | Delete
-- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6
[1524] Fix | Delete
*/
[1525] Fix | Delete
$response = $this->_get_sftp_packet();
[1526] Fix | Delete
if ($this->packet_type != NET_SFTP_STATUS) {
[1527] Fix | Delete
user_error('Expected SSH_FXP_STATUS');
[1528] Fix | Delete
[1529] Fix | Delete
return false;
[1530] Fix | Delete
}
[1531] Fix | Delete
[1532] Fix | Delete
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
[1533] Fix | Delete
if ($status != NET_SFTP_STATUS_OK) {
[1534] Fix | Delete
$this->_logError($response, $status);
[1535] Fix | Delete
[1536] Fix | Delete
return false;
[1537] Fix | Delete
}
[1538] Fix | Delete
[1539] Fix | Delete
return true;
[1540] Fix | Delete
}
[1541] Fix | Delete
[1542] Fix | Delete
/**
[1543] Fix | Delete
* Recursively sets information on directories on the SFTP server
[1544] Fix | Delete
*
[1545] Fix | Delete
* Minimizes directory lookups and SSH_FXP_STATUS requests for speed.
[1546] Fix | Delete
*
[1547] Fix | Delete
* @param String $path
[1548] Fix | Delete
* @param String $attr
[1549] Fix | Delete
* @param Integer $i
[1550] Fix | Delete
*
[1551] Fix | Delete
* @return Boolean
[1552] Fix | Delete
* @access private
[1553] Fix | Delete
*/
[1554] Fix | Delete
public function _setstat_recursive($path, $attr, &$i)
[1555] Fix | Delete
{
[1556] Fix | Delete
if (!$this->_read_put_responses($i)) {
[1557] Fix | Delete
return false;
[1558] Fix | Delete
}
[1559] Fix | Delete
$i = 0;
[1560] Fix | Delete
$entries = $this->_list($path, true, false);
[1561] Fix | Delete
[1562] Fix | Delete
if ($entries === false) {
[1563] Fix | Delete
return $this->_setstat($path, $attr, false);
[1564] Fix | Delete
}
[1565] Fix | Delete
[1566] Fix | Delete
// normally $entries would have at least . and .. but it might not if the directories
[1567] Fix | Delete
// permissions didn't allow reading
[1568] Fix | Delete
if (empty($entries)) {
[1569] Fix | Delete
return false;
[1570] Fix | Delete
}
[1571] Fix | Delete
[1572] Fix | Delete
foreach ($entries as $filename => $props) {
[1573] Fix | Delete
if ($filename == '.' || $filename == '..') {
[1574] Fix | Delete
continue;
[1575] Fix | Delete
}
[1576] Fix | Delete
[1577] Fix | Delete
if (!isset($props['type'])) {
[1578] Fix | Delete
return false;
[1579] Fix | Delete
}
[1580] Fix | Delete
[1581] Fix | Delete
$temp = $path.'/'.$filename;
[1582] Fix | Delete
if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) {
[1583] Fix | Delete
if (!$this->_setstat_recursive($temp, $attr, $i)) {
[1584] Fix | Delete
return false;
[1585] Fix | Delete
}
[1586] Fix | Delete
} else {
[1587] Fix | Delete
if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($temp), $temp, $attr))) {
[1588] Fix | Delete
return false;
[1589] Fix | Delete
}
[1590] Fix | Delete
[1591] Fix | Delete
$i++;
[1592] Fix | Delete
[1593] Fix | Delete
if ($i >= NET_SFTP_QUEUE_SIZE) {
[1594] Fix | Delete
if (!$this->_read_put_responses($i)) {
[1595] Fix | Delete
return false;
[1596] Fix | Delete
}
[1597] Fix | Delete
$i = 0;
[1598] Fix | Delete
}
[1599] Fix | Delete
}
[1600] Fix | Delete
}
[1601] Fix | Delete
[1602] Fix | Delete
if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($path), $path, $attr))) {
[1603] Fix | Delete
return false;
[1604] Fix | Delete
}
[1605] Fix | Delete
[1606] Fix | Delete
$i++;
[1607] Fix | Delete
[1608] Fix | Delete
if ($i >= NET_SFTP_QUEUE_SIZE) {
[1609] Fix | Delete
if (!$this->_read_put_responses($i)) {
[1610] Fix | Delete
return false;
[1611] Fix | Delete
}
[1612] Fix | Delete
$i = 0;
[1613] Fix | Delete
}
[1614] Fix | Delete
[1615] Fix | Delete
return true;
[1616] Fix | Delete
}
[1617] Fix | Delete
[1618] Fix | Delete
/**
[1619] Fix | Delete
* Return the target of a symbolic link
[1620] Fix | Delete
*
[1621] Fix | Delete
* @param String $link
[1622] Fix | Delete
*
[1623] Fix | Delete
* @return Mixed
[1624] Fix | Delete
* @access public
[1625] Fix | Delete
*/
[1626] Fix | Delete
public function readlink($link)
[1627] Fix | Delete
{
[1628] Fix | Delete
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
[1629] Fix | Delete
return false;
[1630] Fix | Delete
}
[1631] Fix | Delete
[1632] Fix | Delete
$link = $this->_realpath($link);
[1633] Fix | Delete
[1634] Fix | Delete
if (!$this->_send_sftp_packet(NET_SFTP_READLINK, pack('Na*', strlen($link), $link))) {
[1635] Fix | Delete
return false;
[1636] Fix | Delete
}
[1637] Fix | Delete
[1638] Fix | Delete
$response = $this->_get_sftp_packet();
[1639] Fix | Delete
switch ($this->packet_type) {
[1640] Fix | Delete
case NET_SFTP_NAME:
[1641] Fix | Delete
break;
[1642] Fix | Delete
case NET_SFTP_STATUS:
[1643] Fix | Delete
$this->_logError($response);
[1644] Fix | Delete
[1645] Fix | Delete
return false;
[1646] Fix | Delete
default:
[1647] Fix | Delete
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
[1648] Fix | Delete
[1649] Fix | Delete
return false;
[1650] Fix | Delete
}
[1651] Fix | Delete
[1652] Fix | Delete
extract(unpack('Ncount', $this->_string_shift($response, 4)));
[1653] Fix | Delete
// the file isn't a symlink
[1654] Fix | Delete
if (!$count) {
[1655] Fix | Delete
return false;
[1656] Fix | Delete
}
[1657] Fix | Delete
[1658] Fix | Delete
extract(unpack('Nlength', $this->_string_shift($response, 4)));
[1659] Fix | Delete
[1660] Fix | Delete
return $this->_string_shift($response, $length);
[1661] Fix | Delete
}
[1662] Fix | Delete
[1663] Fix | Delete
/**
[1664] Fix | Delete
* Create a symlink
[1665] Fix | Delete
*
[1666] Fix | Delete
* symboliclink() creates a symbolic link to the existing target with the specified name link.
[1667] Fix | Delete
*
[1668] Fix | Delete
* @param String $target
[1669] Fix | Delete
* @param String $link
[1670] Fix | Delete
*
[1671] Fix | Delete
* @return Boolean
[1672] Fix | Delete
* @access public
[1673] Fix | Delete
*
[1674] Fix | Delete
* Warning: DO NOT call this function "s y m l i n k", the whole file gets deleted by some "very advanced" antivirus checker.
[1675] Fix | Delete
*/
[1676] Fix | Delete
public function symboliclink($target, $link)
[1677] Fix | Delete
{
[1678] Fix | Delete
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
[1679] Fix | Delete
return false;
[1680] Fix | Delete
}
[1681] Fix | Delete
[1682] Fix | Delete
$target = $this->_realpath($target);
[1683] Fix | Delete
$link = $this->_realpath($link);
[1684] Fix | Delete
[1685] Fix | Delete
$packet = pack('Na*Na*', strlen($target), $target, strlen($link), $link);
[1686] Fix | Delete
if (!$this->_send_sftp_packet(NET_SFTP_SYMLINK, $packet)) {
[1687] Fix | Delete
return false;
[1688] Fix | Delete
}
[1689] Fix | Delete
[1690] Fix | Delete
$response = $this->_get_sftp_packet();
[1691] Fix | Delete
if ($this->packet_type != NET_SFTP_STATUS) {
[1692] Fix | Delete
user_error('Expected SSH_FXP_STATUS');
[1693] Fix | Delete
[1694] Fix | Delete
return false;
[1695] Fix | Delete
}
[1696] Fix | Delete
[1697] Fix | Delete
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
[1698] Fix | Delete
if ($status != NET_SFTP_STATUS_OK) {
[1699] Fix | Delete
$this->_logError($response, $status);
[1700] Fix | Delete
[1701] Fix | Delete
return false;
[1702] Fix | Delete
}
[1703] Fix | Delete
[1704] Fix | Delete
return true;
[1705] Fix | Delete
}
[1706] Fix | Delete
[1707] Fix | Delete
/**
[1708] Fix | Delete
* Creates a directory.
[1709] Fix | Delete
*
[1710] Fix | Delete
* @param String $dir
[1711] Fix | Delete
*
[1712] Fix | Delete
* @return Boolean
[1713] Fix | Delete
* @access public
[1714] Fix | Delete
*/
[1715] Fix | Delete
public function mkdir($dir, $mode = -1, $recursive = false)
[1716] Fix | Delete
{
[1717] Fix | Delete
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
[1718] Fix | Delete
return false;
[1719] Fix | Delete
}
[1720] Fix | Delete
[1721] Fix | Delete
$dir = $this->_realpath($dir);
[1722] Fix | Delete
// by not providing any permissions, hopefully the server will use the logged in users umask - their
[1723] Fix | Delete
// default permissions.
[1724] Fix | Delete
$attr = $mode == -1 ? "\0\0\0\0" : pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);
[1725] Fix | Delete
[1726] Fix | Delete
if ($recursive) {
[1727] Fix | Delete
$dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir));
[1728] Fix | Delete
if (empty($dirs[0])) {
[1729] Fix | Delete
array_shift($dirs);
[1730] Fix | Delete
$dirs[0] = '/'.$dirs[0];
[1731] Fix | Delete
}
[1732] Fix | Delete
for ($i = 0; $i < count($dirs); $i++) {
[1733] Fix | Delete
$temp = array_slice($dirs, 0, $i + 1);
[1734] Fix | Delete
$temp = implode('/', $temp);
[1735] Fix | Delete
$result = $this->_mkdir_helper($temp, $attr);
[1736] Fix | Delete
}
[1737] Fix | Delete
[1738] Fix | Delete
return $result;
[1739] Fix | Delete
}
[1740] Fix | Delete
[1741] Fix | Delete
return $this->_mkdir_helper($dir, $attr);
[1742] Fix | Delete
}
[1743] Fix | Delete
[1744] Fix | Delete
/**
[1745] Fix | Delete
* Helper function for directory creation
[1746] Fix | Delete
*
[1747] Fix | Delete
* @param String $dir
[1748] Fix | Delete
*
[1749] Fix | Delete
* @return Boolean
[1750] Fix | Delete
* @access private
[1751] Fix | Delete
*/
[1752] Fix | Delete
public function _mkdir_helper($dir, $attr)
[1753] Fix | Delete
{
[1754] Fix | Delete
if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*a*', strlen($dir), $dir, $attr))) {
[1755] Fix | Delete
return false;
[1756] Fix | Delete
}
[1757] Fix | Delete
[1758] Fix | Delete
$response = $this->_get_sftp_packet();
[1759] Fix | Delete
if ($this->packet_type != NET_SFTP_STATUS) {
[1760] Fix | Delete
user_error('Expected SSH_FXP_STATUS');
[1761] Fix | Delete
[1762] Fix | Delete
return false;
[1763] Fix | Delete
}
[1764] Fix | Delete
[1765] Fix | Delete
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
[1766] Fix | Delete
if ($status != NET_SFTP_STATUS_OK) {
[1767] Fix | Delete
$this->_logError($response, $status);
[1768] Fix | Delete
[1769] Fix | Delete
return false;
[1770] Fix | Delete
}
[1771] Fix | Delete
[1772] Fix | Delete
return true;
[1773] Fix | Delete
}
[1774] Fix | Delete
[1775] Fix | Delete
/**
[1776] Fix | Delete
* Removes a directory.
[1777] Fix | Delete
*
[1778] Fix | Delete
* @param String $dir
[1779] Fix | Delete
*
[1780] Fix | Delete
* @return Boolean
[1781] Fix | Delete
* @access public
[1782] Fix | Delete
*/
[1783] Fix | Delete
public function rmdir($dir)
[1784] Fix | Delete
{
[1785] Fix | Delete
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
[1786] Fix | Delete
return false;
[1787] Fix | Delete
}
[1788] Fix | Delete
[1789] Fix | Delete
$dir = $this->_realpath($dir);
[1790] Fix | Delete
if ($dir === false) {
[1791] Fix | Delete
return false;
[1792] Fix | Delete
}
[1793] Fix | Delete
[1794] Fix | Delete
if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($dir), $dir))) {
[1795] Fix | Delete
return false;
[1796] Fix | Delete
}
[1797] Fix | Delete
[1798] Fix | Delete
$response = $this->_get_sftp_packet();
[1799] Fix | Delete
if ($this->packet_type != NET_SFTP_STATUS) {
[1800] Fix | Delete
user_error('Expected SSH_FXP_STATUS');
[1801] Fix | Delete
[1802] Fix | Delete
return false;
[1803] Fix | Delete
}
[1804] Fix | Delete
[1805] Fix | Delete
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
[1806] Fix | Delete
if ($status != NET_SFTP_STATUS_OK) {
[1807] Fix | Delete
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED?
[1808] Fix | Delete
$this->_logError($response, $status);
[1809] Fix | Delete
[1810] Fix | Delete
return false;
[1811] Fix | Delete
}
[1812] Fix | Delete
[1813] Fix | Delete
$this->_remove_from_stat_cache($dir);
[1814] Fix | Delete
// the following will do a soft delete, which would be useful if you deleted a file
[1815] Fix | Delete
// and then tried to do a stat on the deleted file. the above, in contrast, does
[1816] Fix | Delete
// a hard delete
[1817] Fix | Delete
//$this->_update_stat_cache($dir, false);
[1818] Fix | Delete
[1819] Fix | Delete
return true;
[1820] Fix | Delete
}
[1821] Fix | Delete
[1822] Fix | Delete
/**
[1823] Fix | Delete
* Uploads a file to the SFTP server.
[1824] Fix | Delete
*
[1825] Fix | Delete
* By default, Net_SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
[1826] Fix | Delete
* So, for example, if you set $data to 'filename.ext' and then do Net_SFTP::get(), you will get a file, twelve bytes
[1827] Fix | Delete
* long, containing 'filename.ext' as its contents.
[1828] Fix | Delete
*
[1829] Fix | Delete
* Setting $mode to NET_SFTP_LOCAL_FILE will change the above behavior. With NET_SFTP_LOCAL_FILE, $remote_file will
[1830] Fix | Delete
* contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
[1831] Fix | Delete
* large $remote_file will be, as well.
[1832] Fix | Delete
*
[1833] Fix | Delete
* Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
[1834] Fix | Delete
* care of that, yourself.
[1835] Fix | Delete
*
[1836] Fix | Delete
* $mode can take an additional two parameters - NET_SFTP_RESUME and NET_SFTP_RESUME_START. These are bitwise AND'd with
[1837] Fix | Delete
* $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following:
[1838] Fix | Delete
*
[1839] Fix | Delete
* NET_SFTP_LOCAL_FILE | NET_SFTP_RESUME
[1840] Fix | Delete
*
[1841] Fix | Delete
* If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace
[1842] Fix | Delete
* NET_SFTP_RESUME with NET_SFTP_RESUME_START.
[1843] Fix | Delete
*
[1844] Fix | Delete
* If $mode & (NET_SFTP_RESUME | NET_SFTP_RESUME_START) then NET_SFTP_RESUME_START will be assumed.
[1845] Fix | Delete
*
[1846] Fix | Delete
* $start and $local_start give you more fine grained control over this process and take precident over NET_SFTP_RESUME
[1847] Fix | Delete
* when they're non-negative. ie. $start could let you write at the end of a file (like NET_SFTP_RESUME) or in the middle
[1848] Fix | Delete
* of one. $local_start could let you start your reading from the end of a file (like NET_SFTP_RESUME_START) or in the
[1849] Fix | Delete
* middle of one.
[1850] Fix | Delete
*
[1851] Fix | Delete
* Setting $local_start to > 0 or $mode | NET_SFTP_RESUME_START doesn't do anything unless $mode | NET_SFTP_LOCAL_FILE.
[1852] Fix | Delete
*
[1853] Fix | Delete
* @param String $remote_file
[1854] Fix | Delete
* @param String $data
[1855] Fix | Delete
* @param optional Integer $mode
[1856] Fix | Delete
* @param optional Integer $start
[1857] Fix | Delete
* @param optional Integer $local_start
[1858] Fix | Delete
*
[1859] Fix | Delete
* @return Boolean
[1860] Fix | Delete
* @access public
[1861] Fix | Delete
* @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - Net_SFTP::setMode().
[1862] Fix | Delete
*/
[1863] Fix | Delete
public function put($remote_file, $data, $mode = NET_SFTP_STRING, $start = -1, $local_start = -1)
[1864] Fix | Delete
{
[1865] Fix | Delete
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
[1866] Fix | Delete
return false;
[1867] Fix | Delete
}
[1868] Fix | Delete
[1869] Fix | Delete
$remote_file = $this->_realpath($remote_file);
[1870] Fix | Delete
if ($remote_file === false) {
[1871] Fix | Delete
return false;
[1872] Fix | Delete
}
[1873] Fix | Delete
[1874] Fix | Delete
$this->_remove_from_stat_cache($remote_file);
[1875] Fix | Delete
[1876] Fix | Delete
$flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE;
[1877] Fix | Delete
// according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file."
[1878] Fix | Delete
// in practice, it doesn't seem to do that.
[1879] Fix | Delete
//$flags|= ($mode & NET_SFTP_RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE;
[1880] Fix | Delete
[1881] Fix | Delete
if ($start >= 0) {
[1882] Fix | Delete
$offset = $start;
[1883] Fix | Delete
} elseif ($mode & NET_SFTP_RESUME) {
[1884] Fix | Delete
// if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called
[1885] Fix | Delete
$size = $this->size($remote_file);
[1886] Fix | Delete
$offset = $size !== false ? $size : 0;
[1887] Fix | Delete
} else {
[1888] Fix | Delete
$offset = 0;
[1889] Fix | Delete
$flags |= NET_SFTP_OPEN_TRUNCATE;
[1890] Fix | Delete
}
[1891] Fix | Delete
[1892] Fix | Delete
$packet = pack('Na*N2', strlen($remote_file), $remote_file, $flags, 0);
[1893] Fix | Delete
if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
[1894] Fix | Delete
return false;
[1895] Fix | Delete
}
[1896] Fix | Delete
[1897] Fix | Delete
$response = $this->_get_sftp_packet();
[1898] Fix | Delete
switch ($this->packet_type) {
[1899] Fix | Delete
case NET_SFTP_HANDLE:
[1900] Fix | Delete
$handle = substr($response, 4);
[1901] Fix | Delete
break;
[1902] Fix | Delete
case NET_SFTP_STATUS:
[1903] Fix | Delete
$this->_logError($response);
[1904] Fix | Delete
[1905] Fix | Delete
return false;
[1906] Fix | Delete
default:
[1907] Fix | Delete
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
[1908] Fix | Delete
[1909] Fix | Delete
return false;
[1910] Fix | Delete
}
[1911] Fix | Delete
[1912] Fix | Delete
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
[1913] Fix | Delete
if ($mode & NET_SFTP_LOCAL_FILE) {
[1914] Fix | Delete
if (!is_file($data)) {
[1915] Fix | Delete
user_error("$data is not a valid file");
[1916] Fix | Delete
[1917] Fix | Delete
return false;
[1918] Fix | Delete
}
[1919] Fix | Delete
$fp = @fopen($data, 'rb');
[1920] Fix | Delete
if (!$fp) {
[1921] Fix | Delete
return false;
[1922] Fix | Delete
}
[1923] Fix | Delete
$size = filesize($data);
[1924] Fix | Delete
[1925] Fix | Delete
if ($local_start >= 0) {
[1926] Fix | Delete
fseek($fp, $local_start);
[1927] Fix | Delete
} elseif ($mode & NET_SFTP_RESUME_START) {
[1928] Fix | Delete
// do nothing
[1929] Fix | Delete
} else {
[1930] Fix | Delete
fseek($fp, $offset);
[1931] Fix | Delete
}
[1932] Fix | Delete
} else {
[1933] Fix | Delete
$size = strlen($data);
[1934] Fix | Delete
}
[1935] Fix | Delete
[1936] Fix | Delete
$sent = 0;
[1937] Fix | Delete
$size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;
[1938] Fix | Delete
[1939] Fix | Delete
$sftp_packet_size = 4096; // PuTTY uses 4096
[1940] Fix | Delete
// make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
[1941] Fix | Delete
$sftp_packet_size -= strlen($handle) + 25;
[1942] Fix | Delete
$i = 0;
[1943] Fix | Delete
while ($sent < $size) {
[1944] Fix | Delete
$temp = $mode & NET_SFTP_LOCAL_FILE ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
[1945] Fix | Delete
$subtemp = $offset + $sent;
[1946] Fix | Delete
$packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
[1947] Fix | Delete
if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {
[1948] Fix | Delete
fclose($fp);
[1949] Fix | Delete
[1950] Fix | Delete
return false;
[1951] Fix | Delete
}
[1952] Fix | Delete
$sent += strlen($temp);
[1953] Fix | Delete
[1954] Fix | Delete
$i++;
[1955] Fix | Delete
[1956] Fix | Delete
if ($i == NET_SFTP_QUEUE_SIZE) {
[1957] Fix | Delete
if (!$this->_read_put_responses($i)) {
[1958] Fix | Delete
$i = 0;
[1959] Fix | Delete
break;
[1960] Fix | Delete
}
[1961] Fix | Delete
$i = 0;
[1962] Fix | Delete
}
[1963] Fix | Delete
}
[1964] Fix | Delete
[1965] Fix | Delete
if (!$this->_read_put_responses($i)) {
[1966] Fix | Delete
if ($mode & NET_SFTP_LOCAL_FILE) {
[1967] Fix | Delete
fclose($fp);
[1968] Fix | Delete
}
[1969] Fix | Delete
$this->_close_handle($handle);
[1970] Fix | Delete
[1971] Fix | Delete
return false;
[1972] Fix | Delete
}
[1973] Fix | Delete
[1974] Fix | Delete
if ($mode & NET_SFTP_LOCAL_FILE) {
[1975] Fix | Delete
fclose($fp);
[1976] Fix | Delete
}
[1977] Fix | Delete
[1978] Fix | Delete
return $this->_close_handle($handle);
[1979] Fix | Delete
}
[1980] Fix | Delete
[1981] Fix | Delete
/**
[1982] Fix | Delete
* Reads multiple successive SSH_FXP_WRITE responses
[1983] Fix | Delete
*
[1984] Fix | Delete
* Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i
[1985] Fix | Delete
* SSH_FXP_WRITEs, in succession, and then reading $i responses.
[1986] Fix | Delete
*
[1987] Fix | Delete
* @param Integer $i
[1988] Fix | Delete
*
[1989] Fix | Delete
* @return Boolean
[1990] Fix | Delete
* @access private
[1991] Fix | Delete
*/
[1992] Fix | Delete
public function _read_put_responses($i)
[1993] Fix | Delete
{
[1994] Fix | Delete
while ($i--) {
[1995] Fix | Delete
$response = $this->_get_sftp_packet();
[1996] Fix | Delete
if ($this->packet_type != NET_SFTP_STATUS) {
[1997] Fix | Delete
user_error('Expected SSH_FXP_STATUS');
[1998] Fix | Delete
[1999] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function