PageRenderTime 35ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/gulliver/thirdparty/pear/Net/FTP.php

https://bitbucket.org/ferOnti/processmaker
PHP | 1427 lines | 471 code | 119 blank | 837 comment | 102 complexity | 7b11b52dcd381a94a5f72157000cc067 MD5 | raw file
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Net_FTP main file.
  5. *
  6. * This file must be included to use the Net_FTP package.
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * LICENSE: This source file is subject to version 3.0 of the PHP license
  11. * that is available through the world-wide-web at the following URI:
  12. * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  13. * the PHP License and are unable to obtain it through the web, please
  14. * send a note to license@php.net so we can mail you a copy immediately.
  15. *
  16. * @category Networking
  17. * @package FTP
  18. * @author Tobias Schlitt <toby@php.net>
  19. * @author Jorrit Schippers <jschippers@php.net>
  20. * @copyright 1997-2008 The PHP Group
  21. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  22. * @version CVS: $Id: FTP.php,v 1.53.2.10 2008/05/19 18:01:08 jschippers Exp $
  23. * @link http://pear.php.net/package/Net_FTP
  24. * @since File available since Release 0.0.1
  25. */
  26. /**
  27. * Include PEAR.php to obtain the PEAR base class
  28. */
  29. require_once 'PEAR.php';
  30. /**
  31. * Option to let the ls() method return only files.
  32. *
  33. * @since 1.3
  34. * @name NET_FTP_FILES_ONLY
  35. * @see Net_FTP::ls()
  36. */
  37. define('NET_FTP_FILES_ONLY', 0, true);
  38. /**
  39. * Option to let the ls() method return only directories.
  40. *
  41. * @since 1.3
  42. * @name NET_FTP_DIRS_ONLY
  43. * @see Net_FTP::ls()
  44. */
  45. define('NET_FTP_DIRS_ONLY', 1, true);
  46. /**
  47. * Option to let the ls() method return directories and files (default).
  48. *
  49. * @since 1.3
  50. * @name NET_FTP_DIRS_FILES
  51. * @see Net_FTP::ls()
  52. */
  53. define('NET_FTP_DIRS_FILES', 2, true);
  54. /**
  55. * Option to let the ls() method return the raw directory listing from ftp_rawlist()
  56. *
  57. * @since 1.3
  58. * @name NET_FTP_RAWLIST
  59. * @see Net_FTP::ls()
  60. */
  61. define('NET_FTP_RAWLIST', 3, true);
  62. /**
  63. * Error code to indicate a failed connection
  64. * This error code indicates, that the connection you tryed to set up
  65. * could not be established. Check your connection settings (host & port)!
  66. *
  67. * @since 1.3
  68. * @name NET_FTP_ERR_CONNECT_FAILED
  69. * @see Net_FTP::connect()
  70. */
  71. define('NET_FTP_ERR_CONNECT_FAILED', -1);
  72. /**
  73. * Error code to indicate a failed login
  74. * This error code indicates, that the login to the FTP server failed. Check
  75. * your user data (username & password).
  76. *
  77. * @since 1.3
  78. * @name NET_FTP_ERR_LOGIN_FAILED
  79. * @see Net_FTP::login()
  80. */
  81. define('NET_FTP_ERR_LOGIN_FAILED', -2);
  82. /**
  83. * Error code to indicate a failed directory change
  84. * The cd() method failed. Ensure that the directory you wanted to access exists.
  85. *
  86. * @since 1.3
  87. * @name NET_FTP_ERR_DIRCHANGE_FAILED
  88. * @see Net_FTP::cd()
  89. */
  90. define('NET_FTP_ERR_DIRCHANGE_FAILED', 2); // Compatibillity reasons!
  91. /**
  92. * Error code to indicate that Net_FTP could not determine the current path
  93. * The cwd() method failed and could not determine the path you currently reside
  94. * in on the FTP server.
  95. *
  96. * @since 1.3
  97. * @name NET_FTP_ERR_DETERMINEPATH_FAILED
  98. * @see Net_FTP::pwd()
  99. */
  100. define('NET_FTP_ERR_DETERMINEPATH_FAILED', 4); // Compatibillity reasons!
  101. /**
  102. * Error code to indicate that the creation of a directory failed
  103. * The directory you tryed to create could not be created. Check the
  104. * access rights on the parent directory!
  105. *
  106. * @since 1.3
  107. * @name NET_FTP_ERR_CREATEDIR_FAILED
  108. * @see Net_FTP::mkdir()
  109. */
  110. define('NET_FTP_ERR_CREATEDIR_FAILED', -4);
  111. /**
  112. * Error code to indicate that the EXEC execution failed.
  113. * The execution of a command using EXEC failed. Ensure, that your
  114. * FTP server supports the EXEC command.
  115. *
  116. * @since 1.3
  117. * @name NET_FTP_ERR_EXEC_FAILED
  118. * @see Net_FTP::execute()
  119. */
  120. define('NET_FTP_ERR_EXEC_FAILED', -5);
  121. /**
  122. * Error code to indicate that the SITE command failed.
  123. * The execution of a command using SITE failed. Ensure, that your
  124. * FTP server supports the SITE command.
  125. *
  126. * @since 1.3
  127. * @name NET_FTP_ERR_SITE_FAILED
  128. * @see Net_FTP::site()
  129. */
  130. define('NET_FTP_ERR_SITE_FAILED', -6);
  131. /**
  132. * Error code to indicate that the CHMOD command failed.
  133. * The execution of CHMOD failed. Ensure, that your
  134. * FTP server supports the CHMOD command and that you have the appropriate
  135. * access rights to use CHMOD.
  136. *
  137. * @since 1.3
  138. * @name NET_FTP_ERR_CHMOD_FAILED
  139. * @see Net_FTP::chmod()
  140. */
  141. define('NET_FTP_ERR_CHMOD_FAILED', -7);
  142. /**
  143. * Error code to indicate that a file rename failed
  144. * The renaming of a file on the server failed. Ensure that you have the
  145. * appropriate access rights to rename the file.
  146. *
  147. * @since 1.3
  148. * @name NET_FTP_ERR_RENAME_FAILED
  149. * @see Net_FTP::rename()
  150. */
  151. define('NET_FTP_ERR_RENAME_FAILED', -8);
  152. /**
  153. * Error code to indicate that the MDTM command failed
  154. * The MDTM command is not supported for directories. Ensure that you gave
  155. * a file path to the mdtm() method, not a directory path.
  156. *
  157. * @since 1.3
  158. * @name NET_FTP_ERR_MDTMDIR_UNSUPPORTED
  159. * @see Net_FTP::mdtm()
  160. */
  161. define('NET_FTP_ERR_MDTMDIR_UNSUPPORTED', -9);
  162. /**
  163. * Error code to indicate that the MDTM command failed
  164. * The MDTM command failed. Ensure that your server supports the MDTM command.
  165. *
  166. * @since 1.3
  167. * @name NET_FTP_ERR_MDTM_FAILED
  168. * @see Net_FTP::mdtm()
  169. */
  170. define('NET_FTP_ERR_MDTM_FAILED', -10);
  171. /**
  172. * Error code to indicate that a date returned by the server was misformated
  173. * A date string returned by your server seems to be missformated and could not be
  174. * parsed. Check that the server is configured correctly. If you're sure, please
  175. * send an email to the auhtor with a dumped output of
  176. * $ftp->ls('./', NET_FTP_RAWLIST); to get the date format supported.
  177. *
  178. * @since 1.3
  179. * @name NET_FTP_ERR_DATEFORMAT_FAILED
  180. * @see Net_FTP::mdtm(), Net_FTP::ls()
  181. */
  182. define('NET_FTP_ERR_DATEFORMAT_FAILED', -11);
  183. /**
  184. * Error code to indicate that the SIZE command failed
  185. * The determination of the filesize of a file failed. Ensure that your server
  186. * supports the SIZE command.
  187. *
  188. * @since 1.3
  189. * @name NET_FTP_ERR_SIZE_FAILED
  190. * @see Net_FTP::size()
  191. */
  192. define('NET_FTP_ERR_SIZE_FAILED', -12);
  193. /**
  194. * Error code to indicate that a local file could not be overwritten
  195. * You specified not to overwrite files. Therefore the local file has not been
  196. * overwriten. If you want to get the file overwriten, please set the option to
  197. * do so.
  198. *
  199. * @since 1.3
  200. * @name NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN
  201. * @see Net_FTP::get(), Net_FTP::getRecursive()
  202. */
  203. define('NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN', -13);
  204. /**
  205. * Error code to indicate that a local file could not be overwritten
  206. * Also you specified to overwrite the local file you want to download to,
  207. * it has not been possible to do so. Check that you have the appropriate access
  208. * rights on the local file to overwrite it.
  209. *
  210. * @since 1.3
  211. * @name NET_FTP_ERR_OVERWRITELOCALFILE_FAILED
  212. * @see Net_FTP::get(), Net_FTP::getRecursive()
  213. */
  214. define('NET_FTP_ERR_OVERWRITELOCALFILE_FAILED', -14);
  215. /**
  216. * Error code to indicate that the file you wanted to upload does not exist
  217. * The file you tried to upload does not exist. Ensure that it exists.
  218. *
  219. * @since 1.3
  220. * @name NET_FTP_ERR_LOCALFILENOTEXIST
  221. * @see Net_FTP::put(), Net_FTP::putRecursive()
  222. */
  223. define('NET_FTP_ERR_LOCALFILENOTEXIST', -15);
  224. /**
  225. * Error code to indicate that a remote file could not be overwritten
  226. * You specified not to overwrite files. Therefore the remote file has not been
  227. * overwriten. If you want to get the file overwriten, please set the option to
  228. * do so.
  229. *
  230. * @since 1.3
  231. * @name NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN
  232. * @see Net_FTP::put(), Net_FTP::putRecursive()
  233. */
  234. define('NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN', -16);
  235. /**
  236. * Error code to indicate that the upload of a file failed
  237. * The upload you tried failed. Ensure that you have appropriate access rights
  238. * to upload the desired file.
  239. *
  240. * @since 1.3
  241. * @name NET_FTP_ERR_UPLOADFILE_FAILED
  242. * @see Net_FTP::put(), Net_FTP::putRecursive()
  243. */
  244. define('NET_FTP_ERR_UPLOADFILE_FAILED', -17);
  245. /**
  246. * Error code to indicate that you specified an incorrect directory path
  247. * The remote path you specified seems not to be a directory. Ensure that
  248. * the path you specify is a directory and that the path string ends with
  249. * a /.
  250. *
  251. * @since 1.3
  252. * @name NET_FTP_ERR_REMOTEPATHNODIR
  253. * @see Net_FTP::putRecursive(), Net_FTP::getRecursive()
  254. */
  255. define('NET_FTP_ERR_REMOTEPATHNODIR', -18);
  256. /**
  257. * Error code to indicate that you specified an incorrect directory path
  258. * The local path you specified seems not to be a directory. Ensure that
  259. * the path you specify is a directory and that the path string ends with
  260. * a /.
  261. *
  262. * @since 1.3
  263. * @name NET_FTP_ERR_LOCALPATHNODIR
  264. * @see Net_FTP::putRecursive(), Net_FTP::getRecursive()
  265. */
  266. define('NET_FTP_ERR_LOCALPATHNODIR', -19);
  267. /**
  268. * Error code to indicate that a local directory failed to be created
  269. * You tried to create a local directory through getRecursive() method,
  270. * which has failed. Ensure that you have the appropriate access rights
  271. * to create it.
  272. *
  273. * @since 1.3
  274. * @name NET_FTP_ERR_CREATELOCALDIR_FAILED
  275. * @see Net_FTP::getRecursive()
  276. */
  277. define('NET_FTP_ERR_CREATELOCALDIR_FAILED', -20);
  278. /**
  279. * Error code to indicate that the provided hostname was incorrect
  280. * The hostname you provided was invalid. Ensure to provide either a
  281. * full qualified domain name or an IP address.
  282. *
  283. * @since 1.3
  284. * @name NET_FTP_ERR_HOSTNAMENOSTRING
  285. * @see Net_FTP::setHostname()
  286. */
  287. define('NET_FTP_ERR_HOSTNAMENOSTRING', -21);
  288. /**
  289. * Error code to indicate that the provided port was incorrect
  290. * The port number you provided was invalid. Ensure to provide either a
  291. * a numeric port number greater zero.
  292. *
  293. * @since 1.3
  294. * @name NET_FTP_ERR_PORTLESSZERO
  295. * @see Net_FTP::setPort()
  296. */
  297. define('NET_FTP_ERR_PORTLESSZERO', -22);
  298. /**
  299. * Error code to indicate that you provided an invalid mode constant
  300. * The mode constant you provided was invalid. You may only provide
  301. * FTP_ASCII or FTP_BINARY.
  302. *
  303. * @since 1.3
  304. * @name NET_FTP_ERR_NOMODECONST
  305. * @see Net_FTP::setMode()
  306. */
  307. define('NET_FTP_ERR_NOMODECONST', -23);
  308. /**
  309. * Error code to indicate that you provided an invalid timeout
  310. * The timeout you provided was invalid. You have to provide a timeout greater
  311. * or equal to zero.
  312. *
  313. * @since 1.3
  314. * @name NET_FTP_ERR_TIMEOUTLESSZERO
  315. * @see Net_FTP::Net_FTP(), Net_FTP::setTimeout()
  316. */
  317. define('NET_FTP_ERR_TIMEOUTLESSZERO', -24);
  318. /**
  319. * Error code to indicate that you provided an invalid timeout
  320. * An error occured while setting the timeout. Ensure that you provide a
  321. * valid integer for the timeount and that your PHP installation works
  322. * correctly.
  323. *
  324. * @since 1.3
  325. * @name NET_FTP_ERR_SETTIMEOUT_FAILED
  326. * @see Net_FTP::Net_FTP(), Net_FTP::setTimeout()
  327. */
  328. define('NET_FTP_ERR_SETTIMEOUT_FAILED', -25);
  329. /**
  330. * Error code to indicate that the provided extension file doesn't exist
  331. * The provided extension file does not exist. Ensure to provided an
  332. * existant extension file.
  333. *
  334. * @since 1.3
  335. * @name NET_FTP_ERR_EXTFILENOTEXIST
  336. * @see Net_FTP::getExtensionsFile()
  337. */
  338. define('NET_FTP_ERR_EXTFILENOTEXIST', -26);
  339. /**
  340. * Error code to indicate that the provided extension file is not readable
  341. * The provided extension file is not readable. Ensure to have sufficient
  342. * access rights for it.
  343. *
  344. * @since 1.3
  345. * @name NET_FTP_ERR_EXTFILEREAD_FAILED
  346. * @see Net_FTP::getExtensionsFile()
  347. */
  348. define('NET_FTP_ERR_EXTFILEREAD_FAILED', -27);
  349. /**
  350. * Error code to indicate that the deletion of a file failed
  351. * The specified file could not be deleted. Ensure to have sufficient
  352. * access rights to delete the file.
  353. *
  354. * @since 1.3
  355. * @name NET_FTP_ERR_EXTFILEREAD_FAILED
  356. * @see Net_FTP::rm()
  357. */
  358. define('NET_FTP_ERR_DELETEFILE_FAILED', -28);
  359. /**
  360. * Error code to indicate that the deletion of a directory faild
  361. * The specified file could not be deleted. Ensure to have sufficient
  362. * access rights to delete the file.
  363. *
  364. * @since 1.3
  365. * @name NET_FTP_ERR_EXTFILEREAD_FAILED
  366. * @see Net_FTP::rm()
  367. */
  368. define('NET_FTP_ERR_DELETEDIR_FAILED', -29);
  369. /**
  370. * Error code to indicate that the directory listing failed
  371. * PHP could not list the directory contents on the server. Ensure
  372. * that your server is configured appropriate.
  373. *
  374. * @since 1.3
  375. * @name NET_FTP_ERR_RAWDIRLIST_FAILED
  376. * @see Net_FTP::ls()
  377. */
  378. define('NET_FTP_ERR_RAWDIRLIST_FAILED', -30);
  379. /**
  380. * Error code to indicate that the directory listing failed
  381. * The directory listing format your server uses seems not to
  382. * be supported by Net_FTP. Please send the output of the
  383. * call ls('./', NET_FTP_RAWLIST); to the author of this
  384. * class to get it supported.
  385. *
  386. * @since 1.3
  387. * @name NET_FTP_ERR_DIRLIST_UNSUPPORTED
  388. * @see Net_FTP::ls()
  389. */
  390. define('NET_FTP_ERR_DIRLIST_UNSUPPORTED', -31);
  391. /**
  392. * Error code to indicate failed disconnecting
  393. * This error code indicates, that disconnection was not possible.
  394. *
  395. * @since 1.3
  396. * @name NET_FTP_ERR_DISCONNECT_FAILED
  397. * @see Net_FTP::disconnect()
  398. */
  399. define('NET_FTP_ERR_DISCONNECT_FAILED', -32);
  400. /**
  401. * Error code to indicate that the username you provided was invalid.
  402. * Check that you provided a non-empty string as the username.
  403. *
  404. * @since 1.3
  405. * @name NET_FTP_ERR_USERNAMENOSTRING
  406. * @see Net_FTP::setUsername()
  407. */
  408. define('NET_FTP_ERR_USERNAMENOSTRING', -33);
  409. /**
  410. * Error code to indicate that the username you provided was invalid.
  411. * Check that you provided a non-empty string as the username.
  412. *
  413. * @since 1.3
  414. * @name NET_FTP_ERR_PASSWORDNOSTRING
  415. * @see Net_FTP::setPassword()
  416. */
  417. define('NET_FTP_ERR_PASSWORDNOSTRING', -34);
  418. /**
  419. * Error code to indicate that the provided extension file is not loadable
  420. * The provided extension file is not loadable. Ensure to have a correct file
  421. * syntax.
  422. *
  423. * @since 1.3.3
  424. * @name NET_FTP_ERR_EXTFILELOAD_FAILED
  425. * @see Net_FTP::getExtensionsFile()
  426. */
  427. define('NET_FTP_ERR_EXTFILELOAD_FAILED', -35);
  428. /**
  429. * Class for comfortable FTP-communication
  430. *
  431. * This class provides comfortable communication with FTP-servers. You may do
  432. * everything enabled by the PHP-FTP-extension and further functionalities, like
  433. * recursive-deletion, -up- and -download. Another feature is to create directories
  434. * recursively.
  435. *
  436. * @category Networking
  437. * @package FTP
  438. * @author Tobias Schlitt <toby@php.net>
  439. * @author Jorrit Schippers <jschippers@php.net>
  440. * @copyright 1997-2008 The PHP Group
  441. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  442. * @version Release: 1.3.7
  443. * @link http://pear.php.net/package/Net_FTP
  444. * @since 0.0.1
  445. * @access public
  446. */
  447. class Net_FTP extends PEAR
  448. {
  449. /**
  450. * The host to connect to
  451. *
  452. * @access private
  453. * @var string
  454. */
  455. var $_hostname;
  456. /**
  457. * The port for ftp-connection (standard is 21)
  458. *
  459. * @access private
  460. * @var int
  461. */
  462. var $_port = 21;
  463. /**
  464. * The username for login
  465. *
  466. * @access private
  467. * @var string
  468. */
  469. var $_username;
  470. /**
  471. * The password for login
  472. *
  473. * @access private
  474. * @var string
  475. */
  476. var $_password;
  477. /**
  478. * Determine whether to use passive-mode (true) or active-mode (false)
  479. *
  480. * @access private
  481. * @var bool
  482. */
  483. var $_passv;
  484. /**
  485. * The standard mode for ftp-transfer
  486. *
  487. * @access private
  488. * @var int
  489. */
  490. var $_mode = FTP_BINARY;
  491. /**
  492. * This holds the handle for the ftp-connection
  493. *
  494. * @access private
  495. * @var resource
  496. */
  497. var $_handle;
  498. /**
  499. * Contains the timeout for FTP operations
  500. *
  501. * @access private
  502. * @var int
  503. * @since 1.3
  504. */
  505. var $_timeout = 90;
  506. /**
  507. * Saves file-extensions for ascii- and binary-mode
  508. *
  509. * The array contains 2 sub-arrays ("ascii" and "binary"), which both contain
  510. * file-extensions without the "." (".php" = "php").
  511. *
  512. * @access private
  513. * @var array
  514. */
  515. var $_file_extensions;
  516. /**
  517. * ls match
  518. * Matches the ls entries against a regex and maps the resulting array to
  519. * speaking names
  520. *
  521. * The values are set in the constructor because of line length constaints.
  522. *
  523. * Typical lines for the Windows format:
  524. * 07-05-07 08:40AM 4701 SomeFile.ext
  525. * 04-29-07 10:28PM <DIR> SomeDir
  526. *
  527. * @access private
  528. * @var array
  529. * @since 1.3
  530. */
  531. var $_ls_match = null;
  532. /**
  533. * matcher
  534. * Stores the matcher for the current connection
  535. *
  536. * @access private
  537. * @var array
  538. * @since 1.3
  539. */
  540. var $_matcher = null;
  541. /**
  542. * Holds all Net_FTP_Observer objects
  543. * that wish to be notified of new messages.
  544. *
  545. * @var array
  546. * @access private
  547. * @since 1.3
  548. */
  549. var $_listeners = array();
  550. /**
  551. * This generates a new FTP-Object. The FTP-connection will not be established,
  552. * yet.
  553. * You can leave $host and $port blank, if you want. The $host will not be set
  554. * and the $port will be left at 21. You have to set the $host manualy before
  555. * trying to connect or with the connect() method.
  556. *
  557. * @param string $host (optional) The hostname
  558. * @param int $port (optional) The port
  559. * @param int $timeout (optional) Sets the standard timeout
  560. *
  561. * @access public
  562. * @return void
  563. * @see Net_FTP::setHostname(), Net_FTP::setPort(), Net_FTP::connect()
  564. */
  565. function Net_FTP($host = null, $port = null, $timeout = 90)
  566. {
  567. $this->PEAR();
  568. if (isset($host)) {
  569. $this->setHostname($host);
  570. }
  571. if (isset($port)) {
  572. $this->setPort($port);
  573. }
  574. $this->_timeout = $timeout;
  575. $this->_file_extensions[FTP_ASCII] = array();
  576. $this->_file_extensions[FTP_BINARY] = array();
  577. $this->_ls_match = array(
  578. 'unix' => array(
  579. 'pattern' => '/(?:(d)|.)([rwxts-]{9})\s+(\w+)\s+([\w\d-()?.]+)\s+'.
  580. '([\w\d-()?.]+)\s+(\w+)\s+(\S+\s+\S+\s+\S+)\s+(.+)/',
  581. 'map' => array(
  582. 'is_dir' => 1,
  583. 'rights' => 2,
  584. 'files_inside' => 3,
  585. 'user' => 4,
  586. 'group' => 5,
  587. 'size' => 6,
  588. 'date' => 7,
  589. 'name' => 8,
  590. )
  591. ),
  592. 'windows' => array(
  593. 'pattern' => '/([0-9\-]+)\s+([0-9:APM]+)\s+((<DIR>)|\d+)\s+(.+)/',
  594. 'map' => array(
  595. 'date' => 1,
  596. 'time' => 2,
  597. 'size' => 3,
  598. 'is_dir' => 4,
  599. 'name' => 5,
  600. )
  601. )
  602. );
  603. }
  604. /**
  605. * This function generates the FTP-connection. You can optionally define a
  606. * hostname and/or a port. If you do so, this data is stored inside the object.
  607. *
  608. * @param string $host (optional) The Hostname
  609. * @param int $port (optional) The Port
  610. *
  611. * @access public
  612. * @return mixed True on success, otherwise PEAR::Error
  613. * @see NET_FTP_ERR_CONNECT_FAILED
  614. */
  615. function connect($host = null, $port = null)
  616. {
  617. $this->_matcher = null;
  618. if (isset($host)) {
  619. $this->setHostname($host);
  620. }
  621. if (isset($port)) {
  622. $this->setPort($port);
  623. }
  624. $handle = @ftp_connect($this->getHostname(), $this->getPort(),
  625. $this->_timeout);
  626. if (!$handle) {
  627. return $this->raiseError("Connection to host failed",
  628. NET_FTP_ERR_CONNECT_FAILED);
  629. } else {
  630. $this->_handle =& $handle;
  631. return true;
  632. }
  633. }
  634. /**
  635. * This function close the FTP-connection
  636. *
  637. * @access public
  638. * @return bool|PEAR_Error Returns true on success, PEAR_Error on failure
  639. */
  640. function disconnect()
  641. {
  642. $res = @ftp_close($this->_handle);
  643. if (!$res) {
  644. return PEAR::raiseError('Disconnect failed.',
  645. NET_FTP_ERR_DISCONNECT_FAILED);
  646. }
  647. return true;
  648. }
  649. /**
  650. * This logs you into the ftp-server. You are free to specify username and
  651. * password in this method. If you specify it, the values will be taken into
  652. * the corresponding attributes, if do not specify, the attributes are taken.
  653. *
  654. * @param string $username (optional) The username to use
  655. * @param string $password (optional) The password to use
  656. *
  657. * @access public
  658. * @return mixed True on success, otherwise PEAR::Error
  659. * @see NET_FTP_ERR_LOGIN_FAILED
  660. */
  661. function login($username = null, $password = null)
  662. {
  663. if (!isset($username)) {
  664. $username = $this->getUsername();
  665. } else {
  666. $this->setUsername($username);
  667. }
  668. if (!isset($password)) {
  669. $password = $this->getPassword();
  670. } else {
  671. $this->setPassword($password);
  672. }
  673. $res = @ftp_login($this->_handle, $username, $password);
  674. if (!$res) {
  675. return $this->raiseError("Unable to login", NET_FTP_ERR_LOGIN_FAILED);
  676. } else {
  677. return true;
  678. }
  679. }
  680. /**
  681. * This changes the currently used directory. You can use either an absolute
  682. * directory-path (e.g. "/home/blah") or a relative one (e.g. "../test").
  683. *
  684. * @param string $dir The directory to go to.
  685. *
  686. * @access public
  687. * @return mixed True on success, otherwise PEAR::Error
  688. * @see NET_FTP_ERR_DIRCHANGE_FAILED
  689. */
  690. function cd($dir)
  691. {
  692. $erg = @ftp_chdir($this->_handle, $dir);
  693. if (!$erg) {
  694. return $this->raiseError("Directory change failed",
  695. NET_FTP_ERR_DIRCHANGE_FAILED);
  696. } else {
  697. return true;
  698. }
  699. }
  700. /**
  701. * Show's you the actual path on the server
  702. * This function questions the ftp-handle for the actual selected path and
  703. * returns it.
  704. *
  705. * @access public
  706. * @return mixed The actual path or PEAR::Error
  707. * @see NET_FTP_ERR_DETERMINEPATH_FAILED
  708. */
  709. function pwd()
  710. {
  711. $res = @ftp_pwd($this->_handle);
  712. if (!$res) {
  713. return $this->raiseError("Could not determine the actual path.",
  714. NET_FTP_ERR_DETERMINEPATH_FAILED);
  715. } else {
  716. return $res;
  717. }
  718. }
  719. /**
  720. * This works similar to the mkdir-command on your local machine. You can either
  721. * give it an absolute or relative path. The relative path will be completed
  722. * with the actual selected server-path. (see: pwd())
  723. *
  724. * @param string $dir Absolute or relative dir-path
  725. * @param bool $recursive (optional) Create all needed directories
  726. *
  727. * @access public
  728. * @return mixed True on success, otherwise PEAR::Error
  729. * @see NET_FTP_ERR_CREATEDIR_FAILED
  730. */
  731. function mkdir($dir, $recursive = false)
  732. {
  733. $dir = $this->_constructPath($dir);
  734. $savedir = $this->pwd();
  735. $this->pushErrorHandling(PEAR_ERROR_RETURN);
  736. $e = $this->cd($dir);
  737. $this->popErrorHandling();
  738. if ($e === true) {
  739. $this->cd($savedir);
  740. return true;
  741. }
  742. $this->cd($savedir);
  743. if ($recursive === false) {
  744. $res = @ftp_mkdir($this->_handle, $dir);
  745. if (!$res) {
  746. return $this->raiseError("Creation of '$dir' failed",
  747. NET_FTP_ERR_CREATEDIR_FAILED);
  748. } else {
  749. return true;
  750. }
  751. } else {
  752. // do not look at the first character, as $dir is absolute,
  753. // it will always be a /
  754. if (strpos(substr($dir, 1), '/') === false) {
  755. return $this->mkdir($dir, false);
  756. }
  757. if (substr($dir, -1) == '/') {
  758. $dir = substr($dir, 0, -1);
  759. }
  760. $parent = substr($dir, 0, strrpos($dir, '/'));
  761. $res = $this->mkdir($parent, true);
  762. if ($res === true) {
  763. $res = $this->mkdir($dir, false);
  764. }
  765. if ($res !== true) {
  766. return $res;
  767. }
  768. return true;
  769. }
  770. }
  771. /**
  772. * This method tries executing a command on the ftp, using SITE EXEC.
  773. *
  774. * @param string $command The command to execute
  775. *
  776. * @access public
  777. * @return mixed The result of the command (if successfull), otherwise
  778. * PEAR::Error
  779. * @see NET_FTP_ERR_EXEC_FAILED
  780. */
  781. function execute($command)
  782. {
  783. $res = @ftp_exec($this->_handle, $command);
  784. if (!$res) {
  785. return $this->raiseError("Execution of command '$command' failed.",
  786. NET_FTP_ERR_EXEC_FAILED);
  787. } else {
  788. return $res;
  789. }
  790. }
  791. /**
  792. * Execute a SITE command on the server
  793. * This method tries to execute a SITE command on the ftp server.
  794. *
  795. * @param string $command The command with parameters to execute
  796. *
  797. * @access public
  798. * @return mixed True if successful, otherwise PEAR::Error
  799. * @see NET_FTP_ERR_SITE_FAILED
  800. */
  801. function site($command)
  802. {
  803. $res = @ftp_site($this->_handle, $command);
  804. if (!$res) {
  805. return $this->raiseError("Execution of SITE command '$command' failed.",
  806. NET_FTP_ERR_SITE_FAILED);
  807. } else {
  808. return $res;
  809. }
  810. }
  811. /**
  812. * This method will try to chmod the file specified on the server
  813. * Currently, you must give a number as the the permission argument (777 or
  814. * similar). The file can be either a relative or absolute path.
  815. * NOTE: Some servers do not support this feature. In that case, you will
  816. * get a PEAR error object returned. If successful, the method returns true
  817. *
  818. * @param mixed $target The file or array of files to set permissions for
  819. * @param integer $permissions The mode to set the file permissions to
  820. *
  821. * @access public
  822. * @return mixed True if successful, otherwise PEAR::Error
  823. * @see NET_FTP_ERR_CHMOD_FAILED
  824. */
  825. function chmod($target, $permissions)
  826. {
  827. // If $target is an array: Loop through it.
  828. if (is_array($target)) {
  829. for ($i = 0; $i < count($target); $i++) {
  830. $res = $this->chmod($target[$i], $permissions);
  831. if (PEAR::isError($res)) {
  832. return $res;
  833. } // end if isError
  834. } // end for i < count($target)
  835. } else {
  836. $res = $this->site("CHMOD " . $permissions . " " . $target);
  837. if (!$res) {
  838. return PEAR::raiseError("CHMOD " . $permissions . " " . $target .
  839. " failed", NET_FTP_ERR_CHMOD_FAILED);
  840. } else {
  841. return $res;
  842. }
  843. } // end if is_array
  844. } // end method chmod
  845. /**
  846. * This method will try to chmod a folder and all of its contents
  847. * on the server. The target argument must be a folder or an array of folders
  848. * and the permissions argument have to be an integer (i.e. 777).
  849. * The file can be either a relative or absolute path.
  850. * NOTE: Some servers do not support this feature. In that case, you
  851. * will get a PEAR error object returned. If successful, the method
  852. * returns true
  853. *
  854. * @param mixed $target The folder or array of folders to
  855. * set permissions for
  856. * @param integer $permissions The mode to set the folder
  857. * and file permissions to
  858. *
  859. * @access public
  860. * @return mixed True if successful, otherwise PEAR::Error
  861. * @see NET_FTP_ERR_CHMOD_FAILED, NET_FTP_ERR_DETERMINEPATH_FAILED,
  862. * NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED
  863. */
  864. function chmodRecursive($target, $permissions)
  865. {
  866. static $dir_permissions;
  867. if (!isset($dir_permissions)) { // Making directory specific permissions
  868. $dir_permissions = $this->_makeDirPermissions($permissions);
  869. }
  870. // If $target is an array: Loop through it
  871. if (is_array($target)) {
  872. for ($i = 0; $i < count($target); $i++) {
  873. $res = $this->chmodRecursive($target[$i], $permissions);
  874. if (PEAR::isError($res)) {
  875. return $res;
  876. } // end if isError
  877. } // end for i < count($target)
  878. } else {
  879. $remote_path = $this->_constructPath($target);
  880. // Chmod the directory itself
  881. $result = $this->chmod($remote_path, $dir_permissions);
  882. if (PEAR::isError($result)) {
  883. return $result;
  884. }
  885. // If $remote_path last character is not a slash, add one
  886. if (substr($remote_path, strlen($remote_path)-1) != "/") {
  887. $remote_path .= "/";
  888. }
  889. $dir_list = array();
  890. $mode = NET_FTP_DIRS_ONLY;
  891. $dir_list = $this->ls($remote_path, $mode);
  892. foreach ($dir_list as $dir_entry) {
  893. if ($dir_entry['name'] == '.' || $dir_entry['name'] == '..') {
  894. continue;
  895. }
  896. $remote_path_new = $remote_path.$dir_entry["name"]."/";
  897. // Chmod the directory we're about to enter
  898. $result = $this->chmod($remote_path_new, $dir_permissions);
  899. if (PEAR::isError($result)) {
  900. return $result;
  901. }
  902. $result = $this->chmodRecursive($remote_path_new, $permissions);
  903. if (PEAR::isError($result)) {
  904. return $result;
  905. }
  906. } // end foreach dir_list as dir_entry
  907. $file_list = array();
  908. $mode = NET_FTP_FILES_ONLY;
  909. $file_list = $this->ls($remote_path, $mode);
  910. foreach ($file_list as $file_entry) {
  911. $remote_file = $remote_path.$file_entry["name"];
  912. $result = $this->chmod($remote_file, $permissions);
  913. if (PEAR::isError($result)) {
  914. return $result;
  915. }
  916. } // end foreach $file_list
  917. } // end if is_array
  918. return true; // No errors
  919. } // end method chmodRecursive
  920. /**
  921. * Rename or move a file or a directory from the ftp-server
  922. *
  923. * @param string $remote_from The remote file or directory original to rename or
  924. * move
  925. * @param string $remote_to The remote file or directory final to rename or
  926. * move
  927. *
  928. * @access public
  929. * @return bool $res True on success, otherwise PEAR::Error
  930. * @see NET_FTP_ERR_RENAME_FAILED
  931. */
  932. function rename ($remote_from, $remote_to)
  933. {
  934. $res = @ftp_rename($this->_handle, $remote_from, $remote_to);
  935. if (!$res) {
  936. return $this->raiseError("Could not rename ".$remote_from." to ".
  937. $remote_to." !", NET_FTP_ERR_RENAME_FAILED);
  938. }
  939. return true;
  940. }
  941. /**
  942. * This will return logical permissions mask for directory.
  943. * if directory has to be readable it have also be executable
  944. *
  945. * @param string $permissions File permissions in digits for file (i.e. 666)
  946. *
  947. * @access private
  948. * @return string File permissions in digits for directory (i.e. 777)
  949. */
  950. function _makeDirPermissions($permissions)
  951. {
  952. $permissions = (string)$permissions;
  953. // going through (user, group, world)
  954. for ($i = 0; $i < strlen($permissions); $i++) {
  955. // Read permission is set but execute not yet
  956. if ((int)$permissions{$i} & 4 and !((int)$permissions{$i} & 1)) {
  957. // Adding execute flag
  958. (int)$permissions{$i} = (int)$permissions{$i} + 1;
  959. }
  960. }
  961. return (string)$permissions;
  962. }
  963. /**
  964. * This will return the last modification-time of a file. You can either give
  965. * this function a relative or an absolute path to the file to check.
  966. * NOTE: Some servers will not support this feature and the function works
  967. * only on files, not directories! When successful,
  968. * it will return the last modification-time as a unix-timestamp or, when
  969. * $format is specified, a preformated timestring.
  970. *
  971. * @param string $file The file to check
  972. * @param string $format (optional) The format to give the date back
  973. * if not set, it will return a Unix timestamp
  974. *
  975. * @access public
  976. * @return mixed Unix timestamp, a preformated date-string or PEAR::Error
  977. * @see NET_FTP_ERR_MDTMDIR_UNSUPPORTED, NET_FTP_ERR_MDTM_FAILED,
  978. * NET_FTP_ERR_DATEFORMAT_FAILED
  979. */
  980. function mdtm($file, $format = null)
  981. {
  982. $file = $this->_constructPath($file);
  983. if ($this->_checkDir($file)) {
  984. return $this->raiseError("Filename '$file' seems to be a directory.",
  985. NET_FTP_ERR_MDTMDIR_UNSUPPORTED);
  986. }
  987. $res = @ftp_mdtm($this->_handle, $file);
  988. if ($res == -1) {
  989. return $this->raiseError("Could not get last-modification-date of '".
  990. $file."'.", NET_FTP_ERR_MDTM_FAILED);
  991. }
  992. if (isset($format)) {
  993. $res = date($format, $res);
  994. if (!$res) {
  995. return $this->raiseError("Date-format failed on timestamp '".$res.
  996. "'.", NET_FTP_ERR_DATEFORMAT_FAILED);
  997. }
  998. }
  999. return $res;
  1000. }
  1001. /**
  1002. * This will return the size of a given file in bytes. You can either give this
  1003. * function a relative or an absolute file-path. NOTE: Some servers do not
  1004. * support this feature!
  1005. *
  1006. * @param string $file The file to check
  1007. *
  1008. * @access public
  1009. * @return mixed Size in bytes or PEAR::Error
  1010. * @see NET_FTP_ERR_SIZE_FAILED
  1011. */
  1012. function size($file)
  1013. {
  1014. $file = $this->_constructPath($file);
  1015. $res = @ftp_size($this->_handle, $file);
  1016. if ($res == -1) {
  1017. return $this->raiseError("Could not determine filesize of '$file'.",
  1018. NET_FTP_ERR_SIZE_FAILED);
  1019. } else {
  1020. return $res;
  1021. }
  1022. }
  1023. /**
  1024. * This method returns a directory-list of the current directory or given one.
  1025. * To display the current selected directory, simply set the first parameter to
  1026. * null
  1027. * or leave it blank, if you do not want to use any other parameters.
  1028. * <br><br>
  1029. * There are 4 different modes of listing directories. Either to list only
  1030. * the files (using NET_FTP_FILES_ONLY), to list only directories (using
  1031. * NET_FTP_DIRS_ONLY) or to show both (using NET_FTP_DIRS_FILES, which is
  1032. * default).
  1033. * <br><br>
  1034. * The 4th one is the NET_FTP_RAWLIST, which returns just the array created by
  1035. * the ftp_rawlist()-function build into PHP.
  1036. * <br><br>
  1037. * The other function-modes will return an array containing the requested data.
  1038. * The files and dirs are listed in human-sorted order, but if you select
  1039. * NET_FTP_DIRS_FILES the directories will be added above the files,
  1040. * but although both sorted.
  1041. * <br><br>
  1042. * All elements in the arrays are associative arrays themselves. They have the
  1043. * following structure:
  1044. * <br><br>
  1045. * Dirs:<br>
  1046. * ["name"] => string The name of the directory<br>
  1047. * ["rights"] => string The rights of the directory (in style
  1048. * "rwxr-xr-x")<br>
  1049. * ["user"] => string The owner of the directory<br>
  1050. * ["group"] => string The group-owner of the directory<br>
  1051. * ["files_inside"]=> string The number of files/dirs inside the
  1052. * directory excluding "." and ".."<br>
  1053. * ["date"] => int The creation-date as Unix timestamp<br>
  1054. * ["is_dir"] => bool true, cause this is a dir<br>
  1055. * <br><br>
  1056. * Files:<br>
  1057. * ["name"] => string The name of the file<br>
  1058. * ["size"] => int Size in bytes<br>
  1059. * ["rights"] => string The rights of the file (in style
  1060. * "rwxr-xr-x")<br>
  1061. * ["user"] => string The owner of the file<br>
  1062. * ["group"] => string The group-owner of the file<br>
  1063. * ["date"] => int The creation-date as Unix timestamp<br>
  1064. * ["is_dir"] => bool false, cause this is a file<br>
  1065. *
  1066. * @param string $dir (optional) The directory to list or null, when listing
  1067. * the current directory.
  1068. * @param int $mode (optional) The mode which types to list (files,
  1069. * directories or both).
  1070. *
  1071. * @access public
  1072. * @return mixed The directory list as described above or PEAR::Error on failure
  1073. * @see NET_FTP_DIRS_FILES, NET_FTP_DIRS_ONLY, NET_FTP_FILES_ONLY,
  1074. * NET_FTP_RAWLIST, NET_FTP_ERR_DETERMINEPATH_FAILED,
  1075. * NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED
  1076. */
  1077. function ls($dir = null, $mode = NET_FTP_DIRS_FILES)
  1078. {
  1079. if (!isset($dir)) {
  1080. $dir = @ftp_pwd($this->_handle);
  1081. if (!$dir) {
  1082. return $this->raiseError("Could not retrieve current directory",
  1083. NET_FTP_ERR_DETERMINEPATH_FAILED);
  1084. }
  1085. }
  1086. if (($mode != NET_FTP_FILES_ONLY) && ($mode != NET_FTP_DIRS_ONLY) &&
  1087. ($mode != NET_FTP_RAWLIST)) {
  1088. $mode = NET_FTP_DIRS_FILES;
  1089. }
  1090. switch ($mode) {
  1091. case NET_FTP_DIRS_FILES:
  1092. $res = $this->_lsBoth($dir);
  1093. break;
  1094. case NET_FTP_DIRS_ONLY:
  1095. $res = $this->_lsDirs($dir);
  1096. break;
  1097. case NET_FTP_FILES_ONLY:
  1098. $res = $this->_lsFiles($dir);
  1099. break;
  1100. case NET_FTP_RAWLIST:
  1101. $res = @ftp_rawlist($this->_handle, $dir);
  1102. break;
  1103. }
  1104. return $res;
  1105. }
  1106. /**
  1107. * This method will delete the given file or directory ($path) from the server
  1108. * (maybe recursive).
  1109. *
  1110. * Whether the given string is a file or directory is only determined by the
  1111. * last sign inside the string ("/" or not).
  1112. *
  1113. * If you specify a directory, you can optionally specify $recursive as true,
  1114. * to let the directory be deleted recursive (with all sub-directories and files
  1115. * inherited).
  1116. *
  1117. * You can either give a absolute or relative path for the file / dir. If you
  1118. * choose to use the relative path, it will be automatically completed with the
  1119. * actual selected directory.
  1120. *
  1121. * @param string $path The absolute or relative path to the file/directory.
  1122. * @param bool $recursive (optional)
  1123. *
  1124. * @access public
  1125. * @return mixed True on success, otherwise PEAR::Error
  1126. * @see NET_FTP_ERR_DELETEFILE_FAILED, NET_FTP_ERR_DELETEDIR_FAILED,
  1127. * NET_FTP_ERR_REMOTEPATHNODIR
  1128. */
  1129. function rm($path, $recursive = false)
  1130. {
  1131. $path = $this->_constructPath($path);
  1132. if ($this->_checkDir($path)) {
  1133. if ($recursive) {
  1134. return $this->_rmDirRecursive($path);
  1135. } else {
  1136. return $this->_rmDir($path);
  1137. }
  1138. } else {
  1139. return $this->_rmFile($path);
  1140. }
  1141. }
  1142. /**
  1143. * This function will download a file from the ftp-server. You can either
  1144. * specify an absolute path to the file (beginning with "/") or a relative one,
  1145. * which will be completed with the actual directory you selected on the server.
  1146. * You can specify the path to which the file will be downloaded on the local
  1147. * machine, if the file should be overwritten if it exists (optionally, default
  1148. * is no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file
  1149. * should be downloaded (if you do not specify this, the method tries to
  1150. * determine it automatically from the mode-directory or uses the default-mode,
  1151. * set by you).
  1152. * If you give a relative path to the local-file, the script-path is used as
  1153. * basepath.
  1154. *
  1155. * @param string $remote_file The absolute or relative path to the file to
  1156. * download
  1157. * @param string $local_file The local file to put the downloaded in
  1158. * @param bool $overwrite (optional) Whether to overwrite existing file
  1159. * @param int $mode (optional) Either FTP_ASCII or FTP_BINARY
  1160. *
  1161. * @access public
  1162. * @return mixed True on success, otherwise PEAR::Error
  1163. * @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN,
  1164. * NET_FTP_ERR_OVERWRITELOCALFILE_FAILED,
  1165. * NET_FTP_ERR_OVERWRITELOCALFILE_FAILED
  1166. */
  1167. function get($remote_file, $local_file, $overwrite = false, $mode = null)
  1168. {
  1169. if (!isset($mode)) {
  1170. $mode = $this->checkFileExtension($remote_file);
  1171. }
  1172. $remote_file = $this->_constructPath($remote_file);
  1173. if (@file_exists($local_file) && !$overwrite) {
  1174. return $this->raiseError("Local file '".$local_file.
  1175. "' exists and may not be overwriten.",
  1176. NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN);
  1177. }
  1178. if (@file_exists($local_file) &&
  1179. !@is_writeable($local_file) && $overwrite) {
  1180. return $this->raiseError("Local file '".$local_file.
  1181. "' is not writeable. Can not overwrite.",
  1182. NET_FTP_ERR_OVERWRITELOCALFILE_FAILED);
  1183. }
  1184. if (@function_exists('ftp_nb_get')) {
  1185. $res = @ftp_nb_get($this->_handle, $local_file, $remote_file, $mode);
  1186. while ($res == FTP_MOREDATA) {
  1187. $this->_announce('nb_get');
  1188. $res = @ftp_nb_continue($this->_handle);
  1189. }
  1190. } else {
  1191. $res = @ftp_get($this->_handle, $local_file, $remote_file, $mode);
  1192. }
  1193. if (!$res) {
  1194. return $this->raiseError("File '".$remote_file.
  1195. "' could not be downloaded to '$local_file'.",
  1196. NET_FTP_ERR_OVERWRITELOCALFILE_FAILED);
  1197. } else {
  1198. return true;
  1199. }
  1200. }
  1201. /**
  1202. * This function will upload a file to the ftp-server. You can either specify a
  1203. * absolute path to the remote-file (beginning with "/") or a relative one,
  1204. * which will be completed with the actual directory you selected on the server.
  1205. * You can specify the path from which the file will be uploaded on the local
  1206. * maschine, if the file should be overwritten if it exists (optionally, default
  1207. * is no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file
  1208. * should be downloaded (if you do not specify this, the method tries to
  1209. * determine it automatically from the mode-directory or uses the default-mode,
  1210. * set by you).
  1211. * If you give a relative path to the local-file, the script-path is used as
  1212. * basepath.
  1213. *
  1214. * @param string $local_file The local file to upload
  1215. * @param string $remote_file The absolute or relative path to the file to
  1216. * upload to
  1217. * @param bool $overwrite (optional) Whether to overwrite existing file
  1218. * @param int $mode (optional) Either FTP_ASCII or FTP_BINARY
  1219. *
  1220. * @access public
  1221. * @return mixed True on success, otherwise PEAR::Error
  1222. * @see NET_FTP_ERR_LOCALFILENOTEXIST,
  1223. * NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN,
  1224. * NET_FTP_ERR_UPLOADFILE_FAILED
  1225. */
  1226. function put($local_file, $remote_file, $overwrite = false, $mode = null)
  1227. {
  1228. if (!isset($mode)) {
  1229. $mode = $this->checkFileExtension($local_file);
  1230. }
  1231. $remote_file = $this->_constructPath($remote_file);
  1232. if (!@file_exists($local_file)) {
  1233. return $this->raiseError("Local file '$local_file' does not exist.",
  1234. NET_FTP_ERR_LOCALFILENOTEXIST);
  1235. }
  1236. if ((@ftp_size($this->_handle, $remote_file) != -1) && !$overwrite) {
  1237. return $this->raiseError("Remote file '".$remote_file.
  1238. "' exists and may not be overwriten.",
  1239. NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN);
  1240. }
  1241. if (function_exists('ftp_alloc')) {
  1242. ftp_alloc($this->_handle, filesize($local_file));
  1243. }
  1244. if (function_exists('ftp_nb_put')) {
  1245. $res = @ftp_nb_put($this->_handle, $remote_file, $local_file, $mode);
  1246. while ($res == FTP_MOREDATA) {
  1247. $this->_announce('nb_put');
  1248. $res = @ftp_nb_continue($this->_handle);
  1249. }
  1250. } else {
  1251. $res = @ftp_put($this->_handle, $remote_file, $local_file, $mode);
  1252. }
  1253. if (!$res) {
  1254. return $this->raiseError("File '$local_file' could not be uploaded to '"
  1255. .$remote_file."'.",
  1256. NET_FTP_ERR_UPLOADFILE_FAILED);
  1257. } else {
  1258. return true;
  1259. }
  1260. }
  1261. /**
  1262. * This functionality allows you to transfer a whole directory-structure from
  1263. * the remote-ftp to your local host. You have to give a remote-directory
  1264. * (ending with '/') and the local directory (ending with '/') where to put the
  1265. * files you download.
  1266. * The remote path is automatically completed with the current-remote-dir, if
  1267. * you give a relative path to this function. You can give a relative path for
  1268. * the $local_path, too. Then the script-basedir will be used for comletion of
  1269. * the path.
  1270. * The parameter $overwrite will determine, whether to overwrite existing files
  1271. * or not. Standard for this is false. Fourth you can explicitly set a mode for
  1272. * all transfer actions done. If you do not set this, the method tries to
  1273. * determine the transfer mode by checking your mode-directory for the file
  1274. * extension. If the extension is not inside the mode-directory, it will get
  1275. * your default mode.
  1276. *
  1277. * @param string $remote_path The path to download
  1278. * @param string $local_path The path to download to
  1279. * @param bool $overwrite (optional) Whether to overwrite existing files
  1280. * (true) or not (false, standard).
  1281. * @param int $mode (optional) The transfermode (either FTP_ASCII or
  1282. * FTP_BINARY).
  1283. *
  1284. * @access public
  1285. * @return mixed True on succes, otherwise PEAR::Error
  1286. * @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN,
  1287. * NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED,
  1288. * NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_LOCALPATHNODIR,
  1289. * NET_FTP_ERR_CREATELOCALDIR_FAILED
  1290. */
  1291. function getRecursive($remote_path, $local_path, $overwrite = false,
  1292. $mode = null)
  1293. {
  1294. $remote_path = $this->_constructPath($remote_path);
  1295. if (!$this->_checkDir($remote_path)) {
  1296. return $this->raiseError("Given remote-path '".$remote_path.
  1297. "' seems not to be a directory.",
  1298. NET_FTP_ERR_REMOTEPATHNODIR);
  1299. }
  1300. if (!$this->_checkDir($local_path)) {
  1301. return $this->raiseError("Given local-path '".$local_path.
  1302. "' seems not to be a directory.",
  1303. NET_FTP_ERR_LOCALPATHNODIR);
  1304. }
  1305. if (!@is_dir($local_path)) {
  1306. $res = @mkdir($local_path);
  1307. if (!$res) {
  1308. return $this->raiseError("Could not c