* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.0
* @link http://pear.php.net/package/Net_FTP
* @since 0.0.1
* @access public
*/
class Observer_ProgressUpload extends Net_FTP_Observer
{
var $progress;
/**
* Constructor for the upload observer
*
* @param HTML_Progress &$progress Progress bar
*
* @return void
*/
function Observer_ProgressUpload(&$progress)
{
/* Call the base class constructor. */
parent::Net_FTP_Observer();
/**
Configure the observer:
Be sure to have an indeterminate progress meter when
@link http://www.php.net/manual/en/function.ftp-nb-put.php
stores a file on the FTP server (non-blocking)
*/
$this->progress =& $progress;
$this->progress->setIndeterminate(true);
}
/**
* Notification method
*
* @param mixed $event Variable describing occured event
*
* @return void
*/
function notify($event)
{
$this->progress->display();
$this->progress->sleep();
if ($this->progress->getPercentComplete() == 1) {
$this->progress->setValue(0);
} else {
$this->progress->incValue();
}
}
}
//
// 2. defines the progress meter
//
$meter = new HTML_Progress();
$ui = &$meter->getUI();
$ui->setProgressAttributes(array(
'background-color' => '#e0e0e0'
));
$ui->setStringAttributes(array(
'color' => '#996',
'background-color' => '#CCCC99'
));
$ui->setCellAttributes(array(
'active-color' => '#996'
));
$meter->setAnimSpeed(200);
$meter->setIncrement(10);
$meter->setStringPainted(true); // get space for the string
$meter->setString(""); // but don't paint it
$meter->setIndeterminate(true); // progress meter start in indeterminate mode
?>
FTP/Progress Observer example
toHtml();
@set_time_limit(0); // unlimited time operation (removed 30s default restriction)
$f = new Net_FTP();
//
// 3. connect to the FTP server
//
$ret = $f->connect($ftp['host'], $ftp['port']);
if (PEAR::isError($ret)) {
die($ret->getMessage());
}
printf('connected at %s
', $ftp['host']);
//
// 4. login to the FTP server as a well-known user
//
$ret = $f->login($ftp['user'], $ftp['pass']);
if (PEAR::isError($ret)) {
$f->disconnect();
die($ret->getMessage());
}
printf('login as %s
', $ftp['user']);
//
// 5. changes directory to final destination for upload operation
//
$ret = $f->cd($dest);
if (PEAR::isError($ret)) {
$f->disconnect();
die($ret->getMessage());
}
//
// 6. attachs an instance of the FTP/Progress subclass observer
//
$observer = new Observer_ProgressUpload($meter);
$ok = $f->attach($observer);
if (!$ok) {
die('cannot attach a FTP Observer');
}
//
// 7. moves files on the FTP server
//
foreach ($files as $file) {
$ret = $f->put($file, basename($file), $overwrite);
if (PEAR::isError($ret)) {
if ($ret->getCode() == NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN
&& !$overwrite) {
printf('%s
', $ret->getMessage());
continue; // it is just a warning when \$overwrite variable is false
}
die($ret->getMessage());
}
printf('%s transfer completed
', basename($file));
}
$f->detach($observer);
//
// 8. checks if files are really on the FTP server
//
$ret = $f->ls(null, NET_FTP_RAWLIST);
if (PEAR::isError($ret)) {
$f->disconnect();
die($ret->getMessage());
}
print '';
var_dump($ret);
print '
';
//
// 9. says goodbye to the FTP server !
//
$f->disconnect();
echo 'Done!';
?>
Net_FTP-1.4.0/example/socket.php 0000664 0001750 0001750 00000006177 12500046241 016004 0 ustar kguest kguest
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @link http://pear.php.net/package/Net_FTP
* @since File available since Release 1.3.0
*/
if (isset($_GET['native'])) {
@dl('ftp.so');
}
// Configuration
// Login info
$host = 'localhost';
$user = 'pub';
$pass = 'public';
// Passive mode on/off
$pasv = false;
// List directory
$dir = 'episodes/';
// Upload files
$Uasci = basename($_SERVER['PHP_SELF']);
$Ubinary = 'screenshot.jpg';
// End of configuration
$time = microtime(true);
/**
* Function used by the test suit.
* Spits out test results in readable way
*
* @param mixed $action action
* @param mixed $result result
* @param mixed $msg message
*
* @return false
*/
function dump($action, $result, $msg = false)
{
if (is_bool($result)) {
$result = $result ? 'TRUE' : 'FALSE';
}
if (is_array($result)) {
echo '' .$action. ':' ."\n";
foreach ($result as $key => $value) {
echo ' ' .$key. ': ' .$value. "\n";
}
} else {
echo '' .$action. ':' ."\n";
echo $result;
if ($msg) {
echo ' ( ' .$msg. ' )';
}
echo "\n";
}
echo '
';// . "\n";
flush();
}
/**
* Little test suit
*/
$stream = ftp_connect($host);
if (is_resource($stream)) {
dump('Logging in', $bool = ftp_login($stream, $user, $pass));
if ($bool) {
dump('PWD', ftp_pwd($stream));
dump('Systype', ftp_systype($stream));
dump('CHDIR "'.$dir.'"', ftp_chdir($stream, $dir));
dump('PWD', ftp_pwd($stream));
dump('CDUP', ftp_cdup($stream));
dump('PASSIVE', ftp_pasv($stream, $pasv));
dump('RAWLIST "."', ftp_rawlist($stream, '.'));
dump('CHMOD', ftp_chmod($stream, 0777, 'sfv3.php'));
dump('ALLOCATE', ftp_alloc($stream, filesize($Ubinary), $msg), $msg);
dump('UPLOAD ASCII', ftp_put($stream, $Uasci, $Uasci, FTP_ASCII), $Uasci);
dump('UPLOAD BINARY', ftp_put($stream, $Ubinary, $Ubinary, FTP_BINARY),
$Ubinary);
dump('RAWLIST "."', ftp_rawlist($stream, '.'));
dump('DELETE '.$Uasci, ftp_delete($stream, $Uasci));
dump('DELETE '.$Bbinary, ftp_delete($stream, $Ubinary));
dump('RAWLIST "."', ftp_rawlist($stream, '.'));
}
dump('QUIT', ftp_quit($stream));
}
$end = microtime(true);
echo $end-$time;
?>
Net_FTP-1.4.0/Net/FTP.php 0000775 0001750 0001750 00000250353 12500046241 014240 0 ustar kguest kguest
* @author Jorrit Schippers
* @copyright 1997-2008 The PHP Group
* @license BSD http://www.opensource.org/licenses/bsd-license.php
* @version CVS: $Id$
* @link http://pear.php.net/package/Net_FTP
* @since File available since Release 0.0.1
*/
/**
* Include PEAR.php to obtain the PEAR base class
*/
require_once 'PEAR.php';
/**
* Option to let the ls() method return only files.
*
* @since 1.3
* @name NET_FTP_FILES_ONLY
* @see Net_FTP::ls()
*/
define('NET_FTP_FILES_ONLY', 0, true);
/**
* Option to let the ls() method return only directories.
*
* @since 1.3
* @name NET_FTP_DIRS_ONLY
* @see Net_FTP::ls()
*/
define('NET_FTP_DIRS_ONLY', 1, true);
/**
* Option to let the ls() method return directories and files (default).
*
* @since 1.3
* @name NET_FTP_DIRS_FILES
* @see Net_FTP::ls()
*/
define('NET_FTP_DIRS_FILES', 2, true);
/**
* Option to let the ls() method return the raw directory listing from ftp_rawlist()
*
* @since 1.3
* @name NET_FTP_RAWLIST
* @see Net_FTP::ls()
*/
define('NET_FTP_RAWLIST', 3, true);
/**
* Option to indicate that non-blocking features should not be used in
* put(). This will also disable the listener functionality as a side effect.
*
* @since 1.4a1
* @name NET_FTP_BLOCKING
* @see Net_FTP::put()
*/
define('NET_FTP_BLOCKING', 1, true);
/**
* Option to indicate that non-blocking features should be used if available in
* put(). This will also enable the listener functionality.
*
* This is the default behaviour.
*
* @since 1.4a1
* @name NET_FTP_NONBLOCKING
* @see Net_FTP::put()
*/
define('NET_FTP_NONBLOCKING', 2, true);
/**
* Error code to indicate a failed connection
* This error code indicates, that the connection you tryed to set up
* could not be established. Check your connection settings (host & port)!
*
* @since 1.3
* @name NET_FTP_ERR_CONNECT_FAILED
* @see Net_FTP::connect()
*/
define('NET_FTP_ERR_CONNECT_FAILED', -1);
/**
* Error code to indicate a failed login
* This error code indicates, that the login to the FTP server failed. Check
* your user data (username & password).
*
* @since 1.3
* @name NET_FTP_ERR_LOGIN_FAILED
* @see Net_FTP::login()
*/
define('NET_FTP_ERR_LOGIN_FAILED', -2);
/**
* Error code to indicate a failed directory change
* The cd() method failed. Ensure that the directory you wanted to access exists.
*
* @since 1.3
* @name NET_FTP_ERR_DIRCHANGE_FAILED
* @see Net_FTP::cd()
*/
define('NET_FTP_ERR_DIRCHANGE_FAILED', 2); // Compatibillity reasons!
/**
* Error code to indicate that Net_FTP could not determine the current path
* The pwd() method failed and could not determine the path you currently reside
* in on the FTP server.
*
* @since 1.3
* @name NET_FTP_ERR_DETERMINEPATH_FAILED
* @see Net_FTP::pwd()
*/
define('NET_FTP_ERR_DETERMINEPATH_FAILED', 4); // Compatibillity reasons!
/**
* Error code to indicate that the creation of a directory failed
* The directory you tryed to create could not be created. Check the
* access rights on the parent directory!
*
* @since 1.3
* @name NET_FTP_ERR_CREATEDIR_FAILED
* @see Net_FTP::mkdir()
*/
define('NET_FTP_ERR_CREATEDIR_FAILED', -4);
/**
* Error code to indicate that the EXEC execution failed.
* The execution of a command using EXEC failed. Ensure, that your
* FTP server supports the EXEC command.
*
* @since 1.3
* @name NET_FTP_ERR_EXEC_FAILED
* @see Net_FTP::execute()
*/
define('NET_FTP_ERR_EXEC_FAILED', -5);
/**
* Error code to indicate that the SITE command failed.
* The execution of a command using SITE failed. Ensure, that your
* FTP server supports the SITE command.
*
* @since 1.3
* @name NET_FTP_ERR_SITE_FAILED
* @see Net_FTP::site()
*/
define('NET_FTP_ERR_SITE_FAILED', -6);
/**
* Error code to indicate that the CHMOD command failed.
* The execution of CHMOD failed. Ensure, that your
* FTP server supports the CHMOD command and that you have the appropriate
* access rights to use CHMOD.
*
* @since 1.3
* @name NET_FTP_ERR_CHMOD_FAILED
* @see Net_FTP::chmod()
*/
define('NET_FTP_ERR_CHMOD_FAILED', -7);
/**
* Error code to indicate that a file rename failed
* The renaming of a file on the server failed. Ensure that you have the
* appropriate access rights to rename the file.
*
* @since 1.3
* @name NET_FTP_ERR_RENAME_FAILED
* @see Net_FTP::rename()
*/
define('NET_FTP_ERR_RENAME_FAILED', -8);
/**
* Error code to indicate that the MDTM command failed
* The MDTM command is not supported for directories. Ensure that you gave
* a file path to the mdtm() method, not a directory path.
*
* @since 1.3
* @name NET_FTP_ERR_MDTMDIR_UNSUPPORTED
* @see Net_FTP::mdtm()
*/
define('NET_FTP_ERR_MDTMDIR_UNSUPPORTED', -9);
/**
* Error code to indicate that the MDTM command failed
* The MDTM command failed. Ensure that your server supports the MDTM command.
*
* @since 1.3
* @name NET_FTP_ERR_MDTM_FAILED
* @see Net_FTP::mdtm()
*/
define('NET_FTP_ERR_MDTM_FAILED', -10);
/**
* Error code to indicate that a date returned by the server was misformated
* A date string returned by your server seems to be missformated and could not be
* parsed. Check that the server is configured correctly. If you're sure, please
* send an email to the auhtor with a dumped output of
* $ftp->ls('./', NET_FTP_RAWLIST); to get the date format supported.
*
* @since 1.3
* @name NET_FTP_ERR_DATEFORMAT_FAILED
* @see Net_FTP::mdtm(), Net_FTP::ls()
*/
define('NET_FTP_ERR_DATEFORMAT_FAILED', -11);
/**
* Error code to indicate that the SIZE command failed
* The determination of the filesize of a file failed. Ensure that your server
* supports the SIZE command.
*
* @since 1.3
* @name NET_FTP_ERR_SIZE_FAILED
* @see Net_FTP::size()
*/
define('NET_FTP_ERR_SIZE_FAILED', -12);
/**
* Error code to indicate that a local file could not be overwritten
* You specified not to overwrite files. Therefore the local file has not been
* overwriten. If you want to get the file overwriten, please set the option to
* do so.
*
* @since 1.3
* @name NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN
* @see Net_FTP::get(), Net_FTP::getRecursive()
*/
define('NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN', -13);
/**
* Error code to indicate that a local file could not be overwritten
* Also you specified to overwrite the local file you want to download to,
* it has not been possible to do so. Check that you have the appropriate access
* rights on the local file to overwrite it.
*
* @since 1.3
* @name NET_FTP_ERR_OVERWRITELOCALFILE_FAILED
* @see Net_FTP::get(), Net_FTP::getRecursive()
*/
define('NET_FTP_ERR_OVERWRITELOCALFILE_FAILED', -14);
/**
* Error code to indicate that the file you wanted to upload does not exist
* The file you tried to upload does not exist. Ensure that it exists.
*
* @since 1.3
* @name NET_FTP_ERR_LOCALFILENOTEXIST
* @see Net_FTP::put(), Net_FTP::putRecursive()
*/
define('NET_FTP_ERR_LOCALFILENOTEXIST', -15);
/**
* Error code to indicate that a remote file could not be overwritten
* You specified not to overwrite files. Therefore the remote file has not been
* overwriten. If you want to get the file overwriten, please set the option to
* do so.
*
* @since 1.3
* @name NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN
* @see Net_FTP::put(), Net_FTP::putRecursive()
*/
define('NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN', -16);
/**
* Error code to indicate that the upload of a file failed
* The upload you tried failed. Ensure that you have appropriate access rights
* to upload the desired file.
*
* @since 1.3
* @name NET_FTP_ERR_UPLOADFILE_FAILED
* @see Net_FTP::put(), Net_FTP::putRecursive()
*/
define('NET_FTP_ERR_UPLOADFILE_FAILED', -17);
/**
* Error code to indicate that you specified an incorrect directory path
* The remote path you specified seems not to be a directory. Ensure that
* the path you specify is a directory and that the path string ends with
* a /.
*
* @since 1.3
* @name NET_FTP_ERR_REMOTEPATHNODIR
* @see Net_FTP::putRecursive(), Net_FTP::getRecursive()
*/
define('NET_FTP_ERR_REMOTEPATHNODIR', -18);
/**
* Error code to indicate that you specified an incorrect directory path
* The local path you specified seems not to be a directory. Ensure that
* the path you specify is a directory and that the path string ends with
* a /.
*
* @since 1.3
* @name NET_FTP_ERR_LOCALPATHNODIR
* @see Net_FTP::putRecursive(), Net_FTP::getRecursive()
*/
define('NET_FTP_ERR_LOCALPATHNODIR', -19);
/**
* Error code to indicate that a local directory failed to be created
* You tried to create a local directory through getRecursive() method,
* which has failed. Ensure that you have the appropriate access rights
* to create it.
*
* @since 1.3
* @name NET_FTP_ERR_CREATELOCALDIR_FAILED
* @see Net_FTP::getRecursive()
*/
define('NET_FTP_ERR_CREATELOCALDIR_FAILED', -20);
/**
* Error code to indicate that the provided hostname was incorrect
* The hostname you provided was invalid. Ensure to provide either a
* full qualified domain name or an IP address.
*
* @since 1.3
* @name NET_FTP_ERR_HOSTNAMENOSTRING
* @see Net_FTP::setHostname()
*/
define('NET_FTP_ERR_HOSTNAMENOSTRING', -21);
/**
* Error code to indicate that the provided port was incorrect
* The port number you provided was invalid. Ensure to provide either a
* a numeric port number greater zero.
*
* @since 1.3
* @name NET_FTP_ERR_PORTLESSZERO
* @see Net_FTP::setPort()
*/
define('NET_FTP_ERR_PORTLESSZERO', -22);
/**
* Error code to indicate that you provided an invalid mode constant
* The mode constant you provided was invalid. You may only provide
* FTP_ASCII or FTP_BINARY.
*
* @since 1.3
* @name NET_FTP_ERR_NOMODECONST
* @see Net_FTP::setMode()
*/
define('NET_FTP_ERR_NOMODECONST', -23);
/**
* Error code to indicate that you provided an invalid timeout
* The timeout you provided was invalid. You have to provide a timeout greater
* or equal to zero.
*
* @since 1.3
* @name NET_FTP_ERR_TIMEOUTLESSZERO
* @see Net_FTP::Net_FTP(), Net_FTP::setTimeout()
*/
define('NET_FTP_ERR_TIMEOUTLESSZERO', -24);
/**
* Error code to indicate that you provided an invalid timeout
* An error occured while setting the timeout. Ensure that you provide a
* valid integer for the timeount and that your PHP installation works
* correctly.
*
* @since 1.3
* @name NET_FTP_ERR_SETTIMEOUT_FAILED
* @see Net_FTP::Net_FTP(), Net_FTP::setTimeout()
*/
define('NET_FTP_ERR_SETTIMEOUT_FAILED', -25);
/**
* Error code to indicate that the provided extension file doesn't exist
* The provided extension file does not exist. Ensure to provided an
* existant extension file.
*
* @since 1.3
* @name NET_FTP_ERR_EXTFILENOTEXIST
* @see Net_FTP::getExtensionsFile()
*/
define('NET_FTP_ERR_EXTFILENOTEXIST', -26);
/**
* Error code to indicate that the provided extension file is not readable
* The provided extension file is not readable. Ensure to have sufficient
* access rights for it.
*
* @since 1.3
* @name NET_FTP_ERR_EXTFILEREAD_FAILED
* @see Net_FTP::getExtensionsFile()
*/
define('NET_FTP_ERR_EXTFILEREAD_FAILED', -27);
/**
* Error code to indicate that the deletion of a file failed
* The specified file could not be deleted. Ensure to have sufficient
* access rights to delete the file.
*
* @since 1.3
* @name NET_FTP_ERR_EXTFILEREAD_FAILED
* @see Net_FTP::rm()
*/
define('NET_FTP_ERR_DELETEFILE_FAILED', -28);
/**
* Error code to indicate that the deletion of a directory faild
* The specified file could not be deleted. Ensure to have sufficient
* access rights to delete the file.
*
* @since 1.3
* @name NET_FTP_ERR_EXTFILEREAD_FAILED
* @see Net_FTP::rm()
*/
define('NET_FTP_ERR_DELETEDIR_FAILED', -29);
/**
* Error code to indicate that the directory listing failed
* PHP could not list the directory contents on the server. Ensure
* that your server is configured appropriate.
*
* @since 1.3
* @name NET_FTP_ERR_RAWDIRLIST_FAILED
* @see Net_FTP::ls()
*/
define('NET_FTP_ERR_RAWDIRLIST_FAILED', -30);
/**
* Error code to indicate that the directory listing failed
* The directory listing format your server uses seems not to
* be supported by Net_FTP. Please send the output of the
* call ls('./', NET_FTP_RAWLIST); to the author of this
* class to get it supported.
*
* @since 1.3
* @name NET_FTP_ERR_DIRLIST_UNSUPPORTED
* @see Net_FTP::ls()
*/
define('NET_FTP_ERR_DIRLIST_UNSUPPORTED', -31);
/**
* Error code to indicate failed disconnecting
* This error code indicates, that disconnection was not possible.
*
* @since 1.3
* @name NET_FTP_ERR_DISCONNECT_FAILED
* @see Net_FTP::disconnect()
*/
define('NET_FTP_ERR_DISCONNECT_FAILED', -32);
/**
* Error code to indicate that the username you provided was invalid.
* Check that you provided a non-empty string as the username.
*
* @since 1.3
* @name NET_FTP_ERR_USERNAMENOSTRING
* @see Net_FTP::setUsername()
*/
define('NET_FTP_ERR_USERNAMENOSTRING', -33);
/**
* Error code to indicate that the username you provided was invalid.
* Check that you provided a non-empty string as the username.
*
* @since 1.3
* @name NET_FTP_ERR_PASSWORDNOSTRING
* @see Net_FTP::setPassword()
*/
define('NET_FTP_ERR_PASSWORDNOSTRING', -34);
/**
* Error code to indicate that the provided extension file is not loadable
* The provided extension file is not loadable. Ensure to have a correct file
* syntax.
*
* @since 1.3.3
* @name NET_FTP_ERR_EXTFILELOAD_FAILED
* @see Net_FTP::getExtensionsFile()
*/
define('NET_FTP_ERR_EXTFILELOAD_FAILED', -35);
/**
* Error code to indicate that the directory listing pattern provided is not a
* string.
*
* @since 1.4.0a1
* @name NET_FTP_ERR_ILLEGALPATTERN
* @see Net_FTP::setDirMatcher()
*/
define('NET_FTP_ERR_ILLEGALPATTERN', -36);
/**
* Error code to indicate that the directory listing matcher map provided is not an
* array.
*
* @since 1.4.0a1
* @name NET_FTP_ERR_ILLEGALMAP
* @see Net_FTP::setDirMatcher()
*/
define('NET_FTP_ERR_ILLEGALMAP', -37);
/**
* Error code to indicate that the directory listing matcher map provided contains
* wrong values (ie: it contains non-numerical values)
*
* @since 1.4.0a1
* @name NET_FTP_ERR_ILLEGALMAPVALUE
* @see Net_FTP::setDirMatcher()
*/
define('NET_FTP_ERR_ILLEGALMAPVALUE', -38);
/**
* Error code indicating that bad options were supplied to the
* put() method.
*
* @since 1.4a1
* @name NET_FTP_ERR_BADOPTIONS
* @see Net_FTP::put()
*/
define('NET_FTP_ERR_BADOPTIONS', -39);
/**
* Error code indicating that SSL connection is not supported as either the
* ftp module or OpenSSL support is not statically built into php.
*
* @since 1.4a2
* @name NET_FTP_ERR_NOSSL
* @see Net_FTP::setSsl()
*/
define('NET_FTP_ERR_NOSSL', -40);
/**
* Class for comfortable FTP-communication
*
* This class provides comfortable communication with FTP-servers. You may do
* everything enabled by the PHP-FTP-extension and further functionalities, like
* recursive-deletion, -up- and -download. Another feature is to create directories
* recursively.
*
* @category Networking
* @package FTP
* @author Tobias Schlitt
* @author Jorrit Schippers
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.0
* @link http://pear.php.net/package/Net_FTP
* @since 0.0.1
* @access public
*/
class Net_FTP extends PEAR
{
/**
* The host to connect to
*
* @access private
* @var string
*/
var $_hostname;
/**
* The port for ftp-connection (standard is 21)
*
* @access private
* @var int
*/
var $_port = 21;
/**
* The username for login
*
* @access private
* @var string
*/
var $_username;
/**
* The password for login
*
* @access private
* @var string
*/
var $_password;
/**
* Determine whether to connect through secure SSL connection or not
*
* Is null when it hasn't been explicitly set
*
* @access private
* @var bool
*/
var $_ssl;
/**
* Determine whether to use passive-mode (true) or active-mode (false)
*
* Is null when it hasn't been explicitly set
*
* @access private
* @var bool
*/
var $_passv = null;
/**
* The standard mode for ftp-transfer
*
* @access private
* @var int
*/
var $_mode = FTP_BINARY;
/**
* This holds the handle for the ftp-connection
*
* If null, the connection hasn't been setup yet. If false, the connection
* attempt has failed. Else, it contains an ftp resource.
*
* @access private
* @var resource
*/
var $_handle = null;
/**
* Contains the timeout for FTP operations
*
* @access private
* @var int
* @since 1.3
*/
var $_timeout = 90;
/**
* Saves file-extensions for ascii- and binary-mode
*
* The array is built like this: 'php' => FTP_ASCII, 'png' => FTP_BINARY
*
* @access private
* @var array
*/
var $_file_extensions = array();
/**
* ls match
* Matches the ls entries against a regex and maps the resulting array to
* speaking names
*
* The values are set in the constructor because of line length constaints.
*
* Typical lines for the Windows format:
* 07-05-07 08:40AM 4701 SomeFile.ext
* 04-29-07 10:28PM SomeDir
*
* @access private
* @var array
* @since 1.3
*/
var $_ls_match = null;
/**
* matcher
* Stores the matcher for the current connection
*
* @access private
* @var array
* @since 1.3
*/
var $_matcher = null;
/**
* Holds all Net_FTP_Observer objects
* that wish to be notified of new messages.
*
* @var array
* @access private
* @since 1.3
*/
var $_listeners = array();
/**
* Is true when a login has been performed
* and was successful
*
* @access private
* @var boolean
* @since 1.4
*/
var $_loggedin = false;
/**
* This generates a new FTP-Object. The FTP-connection will not be established,
* yet.
* You can leave $host and $port blank, if you want. The $host will not be set
* and the $port will be left at 21. You have to set the $host manualy before
* trying to connect or with the connect() method.
*
* @param string $host (optional) The hostname
* @param int $port (optional) The port
* @param int $timeout (optional) Sets the standard timeout
*
* @access public
* @return void
* @see Net_FTP::setHostname(), Net_FTP::setPort(), Net_FTP::connect()
*/
function Net_FTP($host = null, $port = null, $timeout = 90)
{
$this->PEAR();
if (isset($host)) {
$this->setHostname($host);
}
if (isset($port)) {
$this->setPort($port);
}
$this->_timeout = $timeout;
$this->_ls_match = array(
'unix' => array(
'pattern' => '/(?:(d)|.)([rwxts-]{9})\s+(\w+)\s+([\w\d-()?.]+)\s+'.
'([\w\d-()?.]+)\s+(\w+)\s+(\S+\s+\S+\s+\S+)\s+(.+)/',
'map' => array(
'is_dir' => 1,
'rights' => 2,
'files_inside' => 3,
'user' => 4,
'group' => 5,
'size' => 6,
'date' => 7,
'name' => 8,
)
),
'windows' => array(
'pattern' => '/([0-9\-]+\s+[0-9:APM]+)\s+(()|\d+)\s+(.+)/',
'map' => array(
'date' => 1,
'size' => 2,
'is_dir' => 3,
'name' => 4,
)
)
);
}
/**
* This function generates the FTP-connection. You can optionally define a
* hostname and/or a port. If you do so, this data is stored inside the object.
*
* @param string $host (optional) The Hostname
* @param int $port (optional) The Port
* @param bool $ssl (optional) Whether to connect through secure SSL connection
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_CONNECT_FAILED
*/
function connect($host = null, $port = null, $ssl = null)
{
$this->_matcher = null;
if (isset($host)) {
$this->setHostname($host);
}
if (isset($port)) {
$this->setPort($port);
}
if (isset($ssl) && is_bool($ssl) && $ssl) {
$this->setSsl();
}
if ($this->getSsl()) {
$handle = @ftp_ssl_connect($this->getHostname(), $this->getPort(),
$this->_timeout);
} else {
$handle = @ftp_connect($this->getHostname(), $this->getPort(),
$this->_timeout);
}
if (!$handle) {
$this->_handle = false;
return $this->raiseError("Connection to host failed",
NET_FTP_ERR_CONNECT_FAILED);
} else {
$this->_handle =& $handle;
return true;
}
}
/**
* This function close the FTP-connection
*
* @access public
* @return bool|PEAR_Error Returns true on success, PEAR_Error on failure
*/
function disconnect()
{
$res = @ftp_close($this->_handle);
if (!$res) {
return PEAR::raiseError('Disconnect failed.',
NET_FTP_ERR_DISCONNECT_FAILED);
}
$this->_handle = null;
return true;
}
/**
* This logs you into the ftp-server. You are free to specify username and
* password in this method. If you specify it, the values will be taken into
* the corresponding attributes, if do not specify, the attributes are taken.
*
* If connect() has not been called yet, a connection will be setup
*
* @param string $username (optional) The username to use
* @param string $password (optional) The password to use
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_LOGIN_FAILED
*/
function login($username = null, $password = null)
{
if ($this->_handle === null) {
$res = $this->connect();
if (PEAR::isError($res)) {
return $res;
}
}
if (!isset($username)) {
$username = $this->getUsername();
} else {
$this->setUsername($username);
}
if (!isset($password)) {
$password = $this->getPassword();
} else {
$this->setPassword($password);
}
$res = @ftp_login($this->_handle, $username, $password);
if (!$res) {
return $this->raiseError("Unable to login", NET_FTP_ERR_LOGIN_FAILED);
} else {
$this->_loggedin = true;
// distinguish between null and false, null means this setting wasn't
// explicitly changed, so we only change it when setPassive or
// setActive was called by the user
if ($this->_passv === true) {
$this->setPassive();
} elseif ($this->_passv === false) {
$this->setActive();
}
return true;
}
}
/**
* This changes the currently used directory. You can use either an absolute
* directory-path (e.g. "/home/blah") or a relative one (e.g. "../test").
*
* @param string $dir The directory to go to.
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_DIRCHANGE_FAILED
*/
function cd($dir)
{
$erg = @ftp_chdir($this->_handle, $dir);
if (!$erg) {
return $this->raiseError("Directory change failed",
NET_FTP_ERR_DIRCHANGE_FAILED);
} else {
return true;
}
}
/**
* Show's you the actual path on the server
* This function questions the ftp-handle for the actual selected path and
* returns it.
*
* @access public
* @return mixed The actual path or PEAR::Error
* @see NET_FTP_ERR_DETERMINEPATH_FAILED
*/
function pwd()
{
$res = @ftp_pwd($this->_handle);
if (!$res) {
return $this->raiseError("Could not determine the actual path.",
NET_FTP_ERR_DETERMINEPATH_FAILED);
} else {
return $res;
}
}
/**
* This works similar to the mkdir-command on your local machine. You can either
* give it an absolute or relative path. The relative path will be completed
* with the actual selected server-path. (see: pwd())
*
* @param string $dir Absolute or relative dir-path
* @param bool $recursive (optional) Create all needed directories
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_CREATEDIR_FAILED
*/
function mkdir($dir, $recursive = false)
{
$dir = $this->_constructPath($dir);
$savedir = $this->pwd();
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$e = $this->cd($dir);
$this->popErrorHandling();
if ($e === true) {
$this->cd($savedir);
return true;
}
$this->cd($savedir);
if ($recursive === false) {
$res = @ftp_mkdir($this->_handle, $dir);
if (!$res) {
return $this->raiseError("Creation of '$dir' failed",
NET_FTP_ERR_CREATEDIR_FAILED);
} else {
return true;
}
} else {
// do not look at the first character, as $dir is absolute,
// it will always be a /
if (strpos(substr($dir, 1), '/') === false) {
return $this->mkdir($dir, false);
}
if (substr($dir, -1) == '/') {
$dir = substr($dir, 0, -1);
}
$parent = substr($dir, 0, strrpos($dir, '/'));
$res = $this->mkdir($parent, true);
if ($res === true) {
$res = $this->mkdir($dir, false);
}
if ($res !== true) {
return $res;
}
return true;
}
}
/**
* This method tries executing a command on the ftp, using SITE EXEC.
*
* @param string $command The command to execute
*
* @access public
* @return mixed The result of the command (if successfull), otherwise
* PEAR::Error
* @see NET_FTP_ERR_EXEC_FAILED
*/
function execute($command)
{
$res = @ftp_exec($this->_handle, $command);
if (!$res) {
return $this->raiseError("Execution of command '$command' failed.",
NET_FTP_ERR_EXEC_FAILED);
} else {
return $res;
}
}
/**
* Execute a SITE command on the server
* This method tries to execute a SITE command on the ftp server.
*
* @param string $command The command with parameters to execute
*
* @access public
* @return mixed True if successful, otherwise PEAR::Error
* @see NET_FTP_ERR_SITE_FAILED
*/
function site($command)
{
$res = @ftp_site($this->_handle, $command);
if (!$res) {
return $this->raiseError("Execution of SITE command '$command' failed.",
NET_FTP_ERR_SITE_FAILED);
} else {
return $res;
}
}
/**
* This method will try to chmod the file specified on the server
* Currently, you must give a number as the the permission argument (777 or
* similar). The file can be either a relative or absolute path.
* NOTE: Some servers do not support this feature. In that case, you will
* get a PEAR error object returned. If successful, the method returns true
*
* @param mixed $target The file or array of files to set permissions for
* @param integer $permissions The mode to set the file permissions to
*
* @access public
* @return mixed True if successful, otherwise PEAR::Error
* @see NET_FTP_ERR_CHMOD_FAILED
*/
function chmod($target, $permissions)
{
// If $target is an array: Loop through it.
if (is_array($target)) {
for ($i = 0; $i < count($target); $i++) {
$res = $this->chmod($target[$i], $permissions);
if (PEAR::isError($res)) {
return $res;
} // end if isError
} // end for i < count($target)
return true;
} else {
$res = $this->site("CHMOD " . $permissions . " " . $target);
if (!$res) {
return PEAR::raiseError("CHMOD " . $permissions . " " . $target .
" failed", NET_FTP_ERR_CHMOD_FAILED);
} else {
return $res;
}
} // end if is_array
} // end method chmod
/**
* This method will try to chmod a folder and all of its contents
* on the server. The target argument must be a folder or an array of folders
* and the permissions argument have to be an integer (i.e. 777).
* The file can be either a relative or absolute path.
* NOTE: Some servers do not support this feature. In that case, you
* will get a PEAR error object returned. If successful, the method
* returns true
*
* @param mixed $target The folder or array of folders to
* set permissions for
* @param integer $permissions The mode to set the folder
* and file permissions to
*
* @access public
* @return mixed True if successful, otherwise PEAR::Error
* @see NET_FTP_ERR_CHMOD_FAILED, NET_FTP_ERR_DETERMINEPATH_FAILED,
* NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED
*/
function chmodRecursive($target, $permissions)
{
static $dir_permissions;
if (!isset($dir_permissions)) { // Making directory specific permissions
$dir_permissions = $this->_makeDirPermissions($permissions);
}
// If $target is an array: Loop through it
if (is_array($target)) {
for ($i = 0; $i < count($target); $i++) {
$res = $this->chmodRecursive($target[$i], $permissions);
if (PEAR::isError($res)) {
return $res;
} // end if isError
} // end for i < count($target)
} else {
$remote_path = $this->_constructPath($target);
// Chmod the directory itself
$result = $this->chmod($remote_path, $dir_permissions);
if (PEAR::isError($result)) {
return $result;
}
// If $remote_path last character is not a slash, add one
if (substr($remote_path, strlen($remote_path)-1) != "/") {
$remote_path .= "/";
}
$dir_list = array();
$mode = NET_FTP_DIRS_ONLY;
$dir_list = $this->ls($remote_path, $mode);
foreach ($dir_list as $dir_entry) {
if ($dir_entry['name'] == '.' || $dir_entry['name'] == '..') {
continue;
}
$remote_path_new = $remote_path.$dir_entry["name"]."/";
// Chmod the directory we're about to enter
$result = $this->chmod($remote_path_new, $dir_permissions);
if (PEAR::isError($result)) {
return $result;
}
$result = $this->chmodRecursive($remote_path_new, $permissions);
if (PEAR::isError($result)) {
return $result;
}
} // end foreach dir_list as dir_entry
$file_list = array();
$mode = NET_FTP_FILES_ONLY;
$file_list = $this->ls($remote_path, $mode);
if (PEAR::isError($file_list)) {
return $file_list;
}
foreach ($file_list as $file_entry) {
$remote_file = $remote_path.$file_entry["name"];
$result = $this->chmod($remote_file, $permissions);
if (PEAR::isError($result)) {
return $result;
}
} // end foreach $file_list
} // end if is_array
return true; // No errors
} // end method chmodRecursive
/**
* Rename or move a file or a directory from the ftp-server
*
* @param string $remote_from The remote file or directory original to rename or
* move
* @param string $remote_to The remote file or directory final to rename or
* move
*
* @access public
* @return bool $res True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_RENAME_FAILED
*/
function rename ($remote_from, $remote_to)
{
$res = @ftp_rename($this->_handle, $remote_from, $remote_to);
if (!$res) {
return $this->raiseError("Could not rename ".$remote_from." to ".
$remote_to." !", NET_FTP_ERR_RENAME_FAILED);
}
return true;
}
/**
* This will return logical permissions mask for directory.
* if directory has to be readable it have also be executable
*
* @param string $permissions File permissions in digits for file (i.e. 666)
*
* @access private
* @return string File permissions in digits for directory (i.e. 777)
*/
function _makeDirPermissions($permissions)
{
$permissions = (string)$permissions;
// going through (user, group, world)
for ($i = 0; $i < strlen($permissions); $i++) {
// Read permission is set but execute not yet
if ((int)$permissions{$i} & 4 and !((int)$permissions{$i} & 1)) {
// Adding execute flag
$permissions{$i} = (int)$permissions{$i} + 1;
}
}
return (string)$permissions;
}
/**
* This will return the last modification-time of a file. You can either give
* this function a relative or an absolute path to the file to check.
* NOTE: Some servers will not support this feature and the function works
* only on files, not directories! When successful,
* it will return the last modification-time as a unix-timestamp or, when
* $format is specified, a preformated timestring.
*
* @param string $file The file to check
* @param string $format (optional) The format to give the date back
* if not set, it will return a Unix timestamp
*
* @access public
* @return mixed Unix timestamp, a preformated date-string or PEAR::Error
* @see NET_FTP_ERR_MDTMDIR_UNSUPPORTED, NET_FTP_ERR_MDTM_FAILED,
* NET_FTP_ERR_DATEFORMAT_FAILED
*/
function mdtm($file, $format = null)
{
$file = $this->_constructPath($file);
if ($this->_checkRemoteDir($file) !== false) {
return $this->raiseError("Filename '$file' seems to be a directory.",
NET_FTP_ERR_MDTMDIR_UNSUPPORTED);
}
$res = @ftp_mdtm($this->_handle, $file);
if ($res == -1) {
return $this->raiseError("Could not get last-modification-date of '".
$file."'.", NET_FTP_ERR_MDTM_FAILED);
}
if (isset($format)) {
$res = date($format, $res);
if (!$res) {
return $this->raiseError("Date-format failed on timestamp '".$res.
"'.", NET_FTP_ERR_DATEFORMAT_FAILED);
}
}
return $res;
}
/**
* This will return the size of a given file in bytes. You can either give this
* function a relative or an absolute file-path. NOTE: Some servers do not
* support this feature!
*
* @param string $file The file to check
*
* @access public
* @return mixed Size in bytes or PEAR::Error
* @see NET_FTP_ERR_SIZE_FAILED
*/
function size($file)
{
$file = $this->_constructPath($file);
$res = @ftp_size($this->_handle, $file);
if ($res == -1) {
return $this->raiseError("Could not determine filesize of '$file'.",
NET_FTP_ERR_SIZE_FAILED);
} else {
return $res;
}
}
/**
* This method returns a directory-list of the current directory or given one.
* To display the current selected directory, simply set the first parameter to
* null
* or leave it blank, if you do not want to use any other parameters.
*
* There are 4 different modes of listing directories. Either to list only
* the files (using NET_FTP_FILES_ONLY), to list only directories (using
* NET_FTP_DIRS_ONLY) or to show both (using NET_FTP_DIRS_FILES, which is
* default).
*
* The 4th one is the NET_FTP_RAWLIST, which returns just the array created by
* the ftp_rawlist()-function build into PHP.
*
* The other function-modes will return an array containing the requested data.
* The files and dirs are listed in human-sorted order, but if you select
* NET_FTP_DIRS_FILES the directories will be added above the files,
* but although both sorted.
*
* All elements in the arrays are associative arrays themselves. They have the
* following structure:
*
* Dirs:
* ["name"] => string The name of the directory
* ["rights"] => string The rights of the directory (in style
* "rwxr-xr-x")
* ["user"] => string The owner of the directory
* ["group"] => string The group-owner of the directory
* ["files_inside"]=> string The number of files/dirs inside the
* directory excluding "." and ".."
* ["date"] => int The creation-date as Unix timestamp
* ["is_dir"] => bool true, cause this is a dir
*
* Files:
* ["name"] => string The name of the file
* ["size"] => int Size in bytes
* ["rights"] => string The rights of the file (in style
* "rwxr-xr-x")
* ["user"] => string The owner of the file
* ["group"] => string The group-owner of the file
* ["date"] => int The creation-date as Unix timestamp
* ["is_dir"] => bool false, cause this is a file
*
* @param string $dir (optional) The directory to list or null, when listing
* the current directory.
* @param int $mode (optional) The mode which types to list (files,
* directories or both).
*
* @access public
* @return mixed The directory list as described above or PEAR::Error on failure
* @see NET_FTP_DIRS_FILES, NET_FTP_DIRS_ONLY, NET_FTP_FILES_ONLY,
* NET_FTP_RAWLIST, NET_FTP_ERR_DETERMINEPATH_FAILED,
* NET_FTP_ERR_RAWDIRLIST_FAILED, NET_FTP_ERR_DIRLIST_UNSUPPORTED
*/
function ls($dir = null, $mode = NET_FTP_DIRS_FILES)
{
if (!isset($dir)) {
$dir = @ftp_pwd($this->_handle);
if (!$dir) {
return $this->raiseError("Could not retrieve current directory",
NET_FTP_ERR_DETERMINEPATH_FAILED);
}
}
if (($mode != NET_FTP_FILES_ONLY) && ($mode != NET_FTP_DIRS_ONLY) &&
($mode != NET_FTP_RAWLIST)) {
$mode = NET_FTP_DIRS_FILES;
}
switch ($mode) {
case NET_FTP_DIRS_FILES:
$res = $this->_lsBoth($dir);
break;
case NET_FTP_DIRS_ONLY:
$res = $this->_lsDirs($dir);
break;
case NET_FTP_FILES_ONLY:
$res = $this->_lsFiles($dir);
break;
case NET_FTP_RAWLIST:
$res = @ftp_rawlist($this->_handle, $dir);
break;
}
return $res;
}
/**
* This method will delete the given file or directory ($path) from the server
* (maybe recursive).
*
* Whether the given string is a file or directory is only determined by the
* last sign inside the string ("/" or not).
*
* If you specify a directory, you can optionally specify $recursive as true,
* to let the directory be deleted recursive (with all sub-directories and files
* inherited).
*
* You can either give a absolute or relative path for the file / dir. If you
* choose to use the relative path, it will be automatically completed with the
* actual selected directory.
*
* @param string $path The absolute or relative path to the file/directory.
* @param bool $recursive Recursively delete everything in $path
* @param bool $filesonly When deleting recursively, only delete files so the
* directory structure is preserved
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_DELETEFILE_FAILED, NET_FTP_ERR_DELETEDIR_FAILED,
* NET_FTP_ERR_REMOTEPATHNODIR
*/
function rm($path, $recursive = false, $filesonly = false)
{
$path = $this->_constructPath($path);
if ($this->_checkRemoteDir($path) === true) {
if ($recursive) {
return $this->_rmDirRecursive($path, $filesonly);
} else {
return $this->_rmDir($path);
}
} else {
return $this->_rmFile($path);
}
}
/**
* This function will download a file from the ftp-server. You can either
* specify an absolute path to the file (beginning with "/") or a relative one,
* which will be completed with the actual directory you selected on the server.
* You can specify the path to which the file will be downloaded on the local
* machine, if the file should be overwritten if it exists (optionally, default
* is no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file
* should be downloaded (if you do not specify this, the method tries to
* determine it automatically from the mode-directory or uses the default-mode,
* set by you).
* If you give a relative path to the local-file, the script-path is used as
* basepath.
*
* @param string $remote_file The absolute or relative path to the file to
* download
* @param string $local_file The local file to put the downloaded in
* @param bool $overwrite (optional) Whether to overwrite existing file
* @param int $mode (optional) Either FTP_ASCII or FTP_BINARY
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN,
* NET_FTP_ERR_OVERWRITELOCALFILE_FAILED,
* NET_FTP_ERR_OVERWRITELOCALFILE_FAILED
*/
function get($remote_file, $local_file, $overwrite = false, $mode = null)
{
if (!isset($mode)) {
$mode = $this->checkFileExtension($remote_file);
}
$remote_file = $this->_constructPath($remote_file);
if (@file_exists($local_file) && !$overwrite) {
return $this->raiseError("Local file '".$local_file.
"' exists and may not be overwriten.",
NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN);
}
if (@file_exists($local_file) &&
!@is_writeable($local_file) && $overwrite) {
return $this->raiseError("Local file '".$local_file.
"' is not writeable. Can not overwrite.",
NET_FTP_ERR_OVERWRITELOCALFILE_FAILED);
}
if (@function_exists('ftp_nb_get')) {
$res = @ftp_nb_get($this->_handle, $local_file, $remote_file, $mode);
while ($res == FTP_MOREDATA) {
$this->_announce('nb_get');
$res = @ftp_nb_continue($this->_handle);
}
} else {
$res = @ftp_get($this->_handle, $local_file, $remote_file, $mode);
}
if (!$res) {
return $this->raiseError("File '".$remote_file.
"' could not be downloaded to '$local_file'.",
NET_FTP_ERR_OVERWRITELOCALFILE_FAILED);
} else {
return true;
}
}
/**
* This function will upload a file to the ftp-server. You can either specify a
* absolute path to the remote-file (beginning with "/") or a relative one,
* which will be completed with the actual directory you selected on the server.
* You can specify the path from which the file will be uploaded on the local
* maschine, if the file should be overwritten if it exists (optionally, default
* is no overwriting) and in which mode (FTP_ASCII or FTP_BINARY) the file
* should be downloaded (if you do not specify this, the method tries to
* determine it automatically from the mode-directory or uses the default-mode,
* set by you).
* If you give a relative path to the local-file, the script-path is used as
* basepath.
*
* @param string $local_file The local file to upload
* @param string $remote_file The absolute or relative path to the file to
* upload to
* @param bool $overwrite (optional) Whether to overwrite existing file
* @param int $mode (optional) Either FTP_ASCII or FTP_BINARY
* @param int $options (optional) Flags describing the behaviour of this
* function. Currently NET_FTP_BLOCKING and
* NET_FTP_NONBLOCKING are supported, of which
* NET_FTP_NONBLOCKING is the default.
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_LOCALFILENOTEXIST,
* NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN,
* NET_FTP_ERR_UPLOADFILE_FAILED, NET_FTP_NONBLOCKING, NET_FTP_BLOCKING
*/
function put($local_file, $remote_file, $overwrite = false, $mode = null,
$options = 0)
{
if ($options & (NET_FTP_BLOCKING | NET_FTP_NONBLOCKING) ===
(NET_FTP_BLOCKING | NET_FTP_NONBLOCKING)) {
return $this->raiseError('Bad options given: NET_FTP_NONBLOCKING and '.
'NET_FTP_BLOCKING can\'t both be set',
NET_FTP_ERR_BADOPTIONS);
}
$usenb = ! ($options & (NET_FTP_BLOCKING == NET_FTP_BLOCKING));
if (!isset($mode)) {
$mode = $this->checkFileExtension($local_file);
}
$remote_file = $this->_constructPath($remote_file);
if (!@file_exists($local_file)) {
return $this->raiseError("Local file '$local_file' does not exist.",
NET_FTP_ERR_LOCALFILENOTEXIST);
}
if ((@ftp_size($this->_handle, $remote_file) != -1) && !$overwrite) {
return $this->raiseError("Remote file '".$remote_file.
"' exists and may not be overwriten.",
NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN);
}
if (function_exists('ftp_alloc')) {
ftp_alloc($this->_handle, filesize($local_file));
}
if ($usenb && function_exists('ftp_nb_put')) {
$res = @ftp_nb_put($this->_handle, $remote_file, $local_file, $mode);
while ($res == FTP_MOREDATA) {
$this->_announce('nb_put');
$res = @ftp_nb_continue($this->_handle);
}
} else {
$res = @ftp_put($this->_handle, $remote_file, $local_file, $mode);
}
if (!$res) {
return $this->raiseError("File '$local_file' could not be uploaded to '"
.$remote_file."'.",
NET_FTP_ERR_UPLOADFILE_FAILED);
} else {
return true;
}
}
/**
* This functionality allows you to transfer a whole directory-structure from
* the remote-ftp to your local host. You have to give a remote-directory
* (ending with '/') and the local directory (ending with '/') where to put the
* files you download.
* The remote path is automatically completed with the current-remote-dir, if
* you give a relative path to this function. You can give a relative path for
* the $local_path, too. Then the script-basedir will be used for comletion of
* the path.
* The parameter $overwrite will determine, whether to overwrite existing files
* or not. Standard for this is false. Fourth you can explicitly set a mode for
* all transfer actions done. If you do not set this, the method tries to
* determine the transfer mode by checking your mode-directory for the file
* extension. If the extension is not inside the mode-directory, it will get
* your default mode.
*
* Since 1.4 no error will be returned when a file exists while $overwrite is
* set to false.
*
* @param string $remote_path The path to download
* @param string $local_path The path to download to
* @param bool $overwrite (optional) Whether to overwrite existing files
* (true) or not (false, standard).
* @param int $mode (optional) The transfermode (either FTP_ASCII or
* FTP_BINARY).
* @param array $excluded_paths (optional) List of remote files or directories to
* exclude from the transfer. All files and
* directories must be stated as absolute paths.
* Note: You must include a trailing slash on directory names.
*
* @access public
* @return mixed True on succes, otherwise PEAR::Error
* @see NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN,
* NET_FTP_ERR_OVERWRITELOCALFILE_FAILED, NET_FTP_ERR_OVERWRITELOCALFILE_FAILED,
* NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_LOCALPATHNODIR,
* NET_FTP_ERR_CREATELOCALDIR_FAILED
*/
function getRecursive($remote_path, $local_path, $overwrite = false,
$mode = null, $excluded_paths = array())
{
$remote_path = $this->_constructPath($remote_path);
if ($this->_checkRemoteDir($remote_path) !== true) {
return $this->raiseError("Given remote-path '".$remote_path.
"' seems not to be a directory.",
NET_FTP_ERR_REMOTEPATHNODIR);
}
if (!@file_exists($local_path)) {
$res = @mkdir($local_path);
if (!$res) {
return $this->raiseError("Could not create dir '$local_path'",
NET_FTP_ERR_CREATELOCALDIR_FAILED);
}
} elseif (!@is_dir($local_path)) {
return $this->raiseError("Given local-path '".$local_path.
"' seems not to be a directory.",
NET_FTP_ERR_LOCALPATHNODIR);
}
$dir_list = array();
$dir_list = $this->ls($remote_path, NET_FTP_DIRS_ONLY);
if (PEAR::isError($dir_list)) {
return $dir_list;
}
foreach ($dir_list as $dir_entry) {
if ($dir_entry['name'] != '.' && $dir_entry['name'] != '..') {
$remote_path_new = $remote_path.$dir_entry["name"]."/";
$local_path_new = $local_path.$dir_entry["name"]."/";
// Check whether the directory should be excluded
if (!in_array($remote_path_new, $excluded_paths)) {
$result = $this->getRecursive($remote_path_new,
$local_path_new, $overwrite, $mode);
if ($this->isError($result)) {
return $result;
}
}
}
}
$file_list = array();
$file_list = $this->ls($remote_path, NET_FTP_FILES_ONLY);
if (PEAR::isError($file_list)) {
return $file_list;
}
foreach ($file_list as $file_entry) {
$remote_file = $remote_path.$file_entry["name"];
$local_file = $local_path.$file_entry["name"];
// Check whether the file should be excluded
if (!in_array($remote_file, $excluded_paths)) {
$result = $this->get($remote_file, $local_file, $overwrite, $mode);
if ($this->isError($result) &&
$result->getCode() != NET_FTP_ERR_OVERWRITELOCALFILE_FORBIDDEN) {
return $result;
}
}
}
return true;
}
/**
* This functionality allows you to transfer a whole directory-structure from
* your local host to the remote-ftp. You have to give a remote-directory
* (ending with '/') and the local directory (ending with '/') where to put the
* files you download. The remote path is automatically completed with the
* current-remote-dir, if you give a relative path to this function. You can
* give a relative path for the $local_path, too. Then the script-basedir will
* be used for comletion of the path.
* The parameter $overwrite will determine, whether to overwrite existing files
* or not.
* Standard for this is false. Fourth you can explicitly set a mode for all
* transfer actions done. If you do not set this, the method tries to determine
* the transfer mode by checking your mode-directory for the file-extension. If
* the extension is not inside the mode-directory, it will get your default
* mode.
*
* @param string $local_path The path to download to
* @param string $remote_path The path to download
* @param bool $overwrite (optional) Whether to overwrite existing files
* (true) or not (false, standard).
* @param int $mode (optional) The transfermode (either FTP_ASCII or
* FTP_BINARY).
* @param array $excluded_paths (optional) List of local files or directories to
* exclude from the transfer. All files and
* directories must be stated as absolute paths.
* Note: You must include a trailing slash on
* directory names.
*
* @access public
* @return mixed True on succes, otherwise PEAR::Error
* @see NET_FTP_ERR_LOCALFILENOTEXIST,
* NET_FTP_ERR_OVERWRITEREMOTEFILE_FORBIDDEN,
* NET_FTP_ERR_UPLOADFILE_FAILED, NET_FTP_ERR_LOCALPATHNODIR,
* NET_FTP_ERR_REMOTEPATHNODIR
*/
function putRecursive($local_path, $remote_path, $overwrite = false,
$mode = null, $excluded_paths = array())
{
$remote_path = $this->_constructPath($remote_path);
if (!file_exists($local_path) || !is_dir($local_path)) {
return $this->raiseError("Given local-path '".$local_path.
"' seems not to be a directory.",
NET_FTP_ERR_LOCALPATHNODIR);
}
// try to create directory if it doesn't exist
$old_path = $this->pwd();
if ($this->isError($this->cd($remote_path))) {
$res = $this->mkdir($remote_path);
if ($this->isError($res)) {
return $res;
}
}
$this->cd($old_path);
if ($this->_checkRemoteDir($remote_path) !== true) {
return $this->raiseError("Given remote-path '".$remote_path.
"' seems not to be a directory.",
NET_FTP_ERR_REMOTEPATHNODIR);
}
$dir_list = $this->_lsLocal($local_path);
foreach ($dir_list["dirs"] as $dir_entry) {
// local directories do not have arrays as entry
$remote_path_new = $remote_path.$dir_entry."/";
$local_path_new = $local_path.$dir_entry."/";
// Check whether the directory should be excluded
if (!in_array($local_path_new, $excluded_paths)) {
$result = $this->putRecursive($local_path_new,
$remote_path_new, $overwrite, $mode,
$excluded_paths);
if ($this->isError($result)) {
return $result;
}
}
}
foreach ($dir_list["files"] as $file_entry) {
$remote_file = $remote_path.$file_entry;
$local_file = $local_path.$file_entry;
// Check whether the file should be excluded
if (!in_array($local_file, $excluded_paths)) {
$result = $this->put($local_file, $remote_file, $overwrite, $mode);
if ($this->isError($result)) {
return $result;
}
}
}
return true;
}
/**
* This checks, whether a file should be transfered in ascii- or binary-mode
* by it's file-extension. If the file-extension is not set or
* the extension is not inside one of the extension-dirs, the actual set
* transfer-mode is returned.
*
* @param string $filename The filename to be checked
*
* @access public
* @return int Either FTP_ASCII or FTP_BINARY
*/
function checkFileExtension($filename)
{
if (($pos = strrpos($filename, '.')) === false) {
return $this->_mode;
} else {
$ext = substr($filename, $pos + 1);
}
if (isset($this->_file_extensions[$ext])) {
return $this->_file_extensions[$ext];
}
return $this->_mode;
}
/**
* Set the hostname
*
* @param string $host The hostname to set
*
* @access public
* @return bool True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_HOSTNAMENOSTRING
*/
function setHostname($host)
{
if (!is_string($host)) {
return PEAR::raiseError("Hostname must be a string.",
NET_FTP_ERR_HOSTNAMENOSTRING);
}
$this->_hostname = $host;
return true;
}
/**
* Set the Port
*
* @param int $port The port to set
*
* @access public
* @return bool True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_PORTLESSZERO
*/
function setPort($port)
{
if (!is_int($port) || ($port < 0)) {
PEAR::raiseError("Invalid port. Has to be integer >= 0",
NET_FTP_ERR_PORTLESSZERO);
}
$this->_port = $port;
return true;
}
/**
* Set to connect through secure SSL connection
*
* @access public
* @return bool True on success, otherwise PEAR::Error
*/
function setSsl()
{
if (!function_exists('ftp_ssl_connect')) {
return PEAR::raiseError('SSL connection not supported. Function ftp_ssl_connect does not exist.',
NET_FTP_ERR_NOSSL);
}
$this->_ssl = true;
return true;
}
/**
* Set the Username
*
* @param string $user The username to set
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_USERNAMENOSTRING
*/
function setUsername($user)
{
if (empty($user) || !is_string($user)) {
return PEAR::raiseError('Username $user invalid.',
NET_FTP_ERR_USERNAMENOSTRING);
}
$this->_username = $user;
return true;
}
/**
* Set the password
*
* @param string $password The password to set
*
* @access private
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_PASSWORDNOSTRING
*/
function setPassword($password)
{
if (empty($password) || !is_string($password)) {
return PEAR::raiseError('Password xxx invalid.',
NET_FTP_ERR_PASSWORDNOSTRING);
}
$this->_password = $password;
return true;
}
/**
* Set the transfer-mode. You can use the predefined constants
* FTP_ASCII or FTP_BINARY. The mode will be stored for any further transfers.
*
* @param int $mode The mode to set
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_NOMODECONST
*/
function setMode($mode)
{
if (($mode == FTP_ASCII) || ($mode == FTP_BINARY)) {
$this->_mode = $mode;
return true;
} else {
return $this->raiseError('FTP-Mode has either to be FTP_ASCII or'.
'FTP_BINARY', NET_FTP_ERR_NOMODECONST);
}
}
/**
* Set the transfer-method to passive mode
*
* @access public
* @return void
*/
function setPassive()
{
$this->_passv = true;
if ($this->_handle != null && $this->_loggedin) {
@ftp_pasv($this->_handle, true);
}
}
/**
* Set the transfer-method to active mode
*
* @access public
* @return void
*/
function setActive()
{
$this->_passv = false;
if ($this->_handle != null && $this->_loggedin) {
@ftp_pasv($this->_handle, false);
}
}
/**
* Set the timeout for FTP operations
*
* Use this method to set a timeout for FTP operation. Timeout has to be an
* integer.
*
* @param int $timeout the timeout to use
*
* @access public
* @return bool True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_TIMEOUTLESSZERO, NET_FTP_ERR_SETTIMEOUT_FAILED
*/
function setTimeout ( $timeout = 0 )
{
if (!is_int($timeout) || ($timeout < 0)) {
return PEAR::raiseError('Timeout '.$timeout.
' is invalid, has to be an integer >= 0',
NET_FTP_ERR_TIMEOUTLESSZERO);
}
$this->_timeout = $timeout;
if (isset($this->_handle) && is_resource($this->_handle)) {
$res = @ftp_set_option($this->_handle, FTP_TIMEOUT_SEC, $timeout);
} else {
$res = true;
}
if (!$res) {
return PEAR::raiseError("Set timeout failed.",
NET_FTP_ERR_SETTIMEOUT_FAILED);
}
return true;
}
/**
* Adds an extension to a mode-directory
*
* The mode-directory saves file-extensions coresponding to filetypes
* (ascii e.g.: 'php', 'txt', 'htm',...; binary e.g.: 'jpg', 'gif', 'exe',...).
* The extensions have to be saved without the '.'. And
* can be predefined in an external file (see: getExtensionsFile()).
*
* The array is build like this: 'php' => FTP_ASCII, 'png' => FTP_BINARY
*
* To change the mode of an extension, just add it again with the new mode!
*
* @param int $mode Either FTP_ASCII or FTP_BINARY
* @param string $ext Extension
*
* @access public
* @return void
*/
function addExtension($mode, $ext)
{
$this->_file_extensions[$ext] = $mode;
}
/**
* This function removes an extension from the mode-directories
* (described above).
*
* @param string $ext The extension to remove
*
* @access public
* @return void
*/
function removeExtension($ext)
{
if (isset($this->_file_extensions[$ext])) {
unset($this->_file_extensions[$ext]);
}
}
/**
* This get's both (ascii- and binary-mode-directories) from the given file.
* Beware, if you read a file into the mode-directory, all former set values
* will be unset!
*
* Example file contents:
* [ASCII]
* asc = 0
* txt = 0
* [BINARY]
* bin = 1
* jpg = 1
*
* @param string $filename The file to get from
*
* @access public
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_EXTFILENOTEXIST, NET_FTP_ERR_EXTFILEREAD_FAILED
*/
function getExtensionsFile($filename)
{
if (!file_exists($filename)) {
return $this->raiseError("Extensions-file '$filename' does not exist",
NET_FTP_ERR_EXTFILENOTEXIST);
}
if (!is_readable($filename)) {
return $this->raiseError("Extensions-file '$filename' is not readable",
NET_FTP_ERR_EXTFILEREAD_FAILED);
}
$exts = @parse_ini_file($filename, true);
if (!is_array($exts)) {
return $this->raiseError("Extensions-file '$filename' could not be".
"loaded", NET_FTP_ERR_EXTFILELOAD_FAILED);
}
$this->_file_extensions = array();
if (isset($exts['ASCII'])) {
foreach (array_keys($exts['ASCII']) as $ext) {
$this->_file_extensions[$ext] = FTP_ASCII;
}
}
if (isset($exts['BINARY'])) {
foreach (array_keys($exts['BINARY']) as $ext) {
$this->_file_extensions[$ext] = FTP_BINARY;
}
}
return true;
}
/**
* Returns the hostname
*
* @access public
* @return string The hostname
*/
function getHostname()
{
return $this->_hostname;
}
/**
* Returns the port
*
* @access public
* @return int The port
*/
function getPort()
{
return $this->_port;
}
/**
* Returns whether to connect through secure SSL connection
*
* @access public
* @return bool True if with SSL, false if without SSL
*/
function getSsl()
{
return $this->_ssl;
}
/**
* Returns the username
*
* @access public
* @return string The username
*/
function getUsername()
{
return $this->_username;
}
/**
* Returns the password
*
* @access public
* @return string The password
*/
function getPassword()
{
return $this->_password;
}
/**
* Returns the transfermode
*
* @access public
* @return int The transfermode, either FTP_ASCII or FTP_BINARY.
*/
function getMode()
{
return $this->_mode;
}
/**
* Returns, whether the connection is set to passive mode or not
*
* @access public
* @return bool True if passive-, false if active-mode
*/
function isPassive()
{
return $this->_passv;
}
/**
* Returns the mode set for a file-extension
*
* @param string $ext The extension you wanna ask for
*
* @return int Either FTP_ASCII, FTP_BINARY or NULL (if not set a mode for it)
* @access public
*/
function getExtensionMode($ext)
{
return @$this->_file_extensions[$ext];
}
/**
* Get the currently set timeout.
* Returns the actual timeout set.
*
* @access public
* @return int The actual timeout
*/
function getTimeout()
{
return ftp_get_option($this->_handle, FTP_TIMEOUT_SEC);
}
/**
* Adds a Net_FTP_Observer instance to the list of observers
* that are listening for messages emitted by this Net_FTP instance.
*
* @param object &$observer The Net_FTP_Observer instance to attach
* as a listener.
*
* @return boolean True if the observer is successfully attached.
* @access public
* @since 1.3
*/
function attach(&$observer)
{
if (!is_a($observer, 'Net_FTP_Observer')) {
return false;
}
$this->_listeners[$observer->getId()] = &$observer;
return true;
}
/**
* Removes a Net_FTP_Observer instance from the list of observers.
*
* @param object $observer The Net_FTP_Observer instance to detach
* from the list of listeners.
*
* @return boolean True if the observer is successfully detached.
* @access public
* @since 1.3
*/
function detach($observer)
{
if (!is_a($observer, 'Net_FTP_Observer') ||
!isset($this->_listeners[$observer->getId()])) {
return false;
}
unset($this->_listeners[$observer->getId()]);
return true;
}
/**
* Sets the directory listing matcher
*
* Use this method to set the directory listing matcher to a specific pattern.
* Indicate the pattern as a perl regular expression and give an array
* containing as keys the fields selected in the regular expression and as
* values the offset of the subpattern in the pattern.
*
* Example:
* $pattern = '/(?:(d)|.)([rwxt-]+)\s+(\w+)\s+([\w\d-]+)\s+([\w\d-]+)\s+(\w+)
* \s+(\S+\s+\S+\s+\S+)\s+(.+)/',
* $matchmap = array(
* 'is_dir' => 1,
* 'rights' => 2,
* 'files_inside' => 3,
* 'user' => 4,
* 'group' => 5,
* 'size' => 6,
* 'date' => 7,
* 'name' => 8,
* )
*
* Make sure at least the is_dir and name keys are set. The is_dir key should
* point to a subpattern that is empty for non-directories and non-empty
* for directories.
*
* @param string $pattern The new matcher pattern to use
* @param array $matchmap An mapping from key to subpattern offset
*
* @since 1.4.0a1
* @access public
* @return bool|PEAR_Error True if matcher set successfully, PEAR_Error
* otherwise
* @see NET_FTP_ERR_ILLEGALPATTERN,
* NET_FTP_ERR_ILLEGALMAP
* NET_FTP_ERR_ILLEGALMAPVALUE
*/
function setDirMatcher($pattern, $matchmap)
{
if (!is_string($pattern)) {
return $this->raiseError('The supplied pattern is not a string',
NET_FTP_ERR_ILLEGALPATTERN);
}
if (!is_array($matchmap)) {
return $this->raiseError('The supplied pattern is not an array',
NET_FTP_ERR_ILLEGALMAP);
} else {
foreach ($matchmap AS $val) {
if (!is_numeric($val)) {
return $this->raiseError('The supplied pattern contains'.
'invalid value '.$val,
NET_FTP_ERR_ILLEGALMAPVALUE);
}
}
}
$this->_matcher = array('pattern' => $pattern, 'map' => $matchmap);
return true;
}
/**
* Informs each registered observer instance that a new message has been
* sent.
*
* @param mixed $event A hash describing the net event.
*
* @access private
* @since 1.3
* @return void
*/
function _announce($event)
{
foreach ($this->_listeners as $listener) {
$listener->notify($event);
}
}
/**
* Rebuild the path, if given relative
*
* This method will make a relative path absolute by prepending the current
* remote directory in front of it.
*
* @param string $path The path to check and construct
*
* @access private
* @return string The build path
*/
function _constructPath($path)
{
if ((substr($path, 0, 1) != '/') && (substr($path, 0, 2) != './')) {
$actual_dir = @ftp_pwd($this->_handle);
if (substr($actual_dir, -1) != '/') {
$actual_dir .= '/';
}
$path = $actual_dir.$path;
}
return $path;
}
/**
* Checks whether the given path is a remote directory by trying to
* chdir() into it (and back out)
*
* @param string $path Path to check
*
* @access private
* @return mixed True if $path is a directory, otherwise false, PEAR_Error
* when an error occurs in determining path type
*/
function _checkRemoteDir($path)
{
$pwd = $this->pwd();
if ($this->isError($pwd)) {
return $pwd;
}
$res = $this->cd($path);
$this->cd($pwd);
return $this->isError($res, NET_FTP_ERR_DIRCHANGE_FAILED) === false;
}
/**
* This will remove a file
*
* @param string $file The file to delete
*
* @access private
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_DELETEFILE_FAILED
*/
function _rmFile($file)
{
if (substr($file, 0, 1) != "/") {
$actual_dir = @ftp_pwd($this->_handle);
if (substr($actual_dir, (strlen($actual_dir) - 2), 1) != "/") {
$actual_dir .= "/";
}
$file = $actual_dir.$file;
}
$res = @ftp_delete($this->_handle, $file);
if (!$res) {
return $this->raiseError("Could not delete file '$file'.",
NET_FTP_ERR_DELETEFILE_FAILED);
} else {
return true;
}
}
/**
* This will remove a dir
*
* @param string $dir The dir to delete
*
* @access private
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED
*/
function _rmDir($dir)
{
if (substr($dir, (strlen($dir) - 1), 1) != "/") {
return $this->raiseError("Directory name '".$dir.
"' is invalid, has to end with '/'",
NET_FTP_ERR_REMOTEPATHNODIR);
}
$res = @ftp_rmdir($this->_handle, $dir);
if (!$res) {
return $this->raiseError("Could not delete directory '$dir'.",
NET_FTP_ERR_DELETEDIR_FAILED);
} else {
return true;
}
}
/**
* This will remove a dir and all subdirs and -files
*
* @param string $dir The dir to delete recursively
* @param bool $filesonly Only delete files so the directory structure is
* preserved
*
* @access private
* @return mixed True on success, otherwise PEAR::Error
* @see NET_FTP_ERR_REMOTEPATHNODIR, NET_FTP_ERR_DELETEDIR_FAILED
*/
function _rmDirRecursive($dir, $filesonly = false)
{
if (substr($dir, (strlen($dir) - 1), 1) != "/") {
return $this->raiseError("Directory name '".$dir.
"' is invalid, has to end with '/'",
NET_FTP_ERR_REMOTEPATHNODIR);
}
$file_list = $this->_lsFiles($dir);
if (PEAR::isError($file_list)) {
return $file_list;
}
foreach ($file_list as $file) {
$file = $dir.$file["name"];
$res = $this->rm($file);
if ($this->isError($res)) {
return $res;
}
}
$dir_list = $this->_lsDirs($dir);
if (PEAR::isError($dir_list)) {
return $dir_list;
}
foreach ($dir_list as $new_dir) {
if ($new_dir["name"] == '.' || $new_dir["name"] == '..') {
continue;
}
$new_dir = $dir.$new_dir["name"]."/";
$res = $this->_rmDirRecursive($new_dir, $filesonly);
if ($this->isError($res)) {
return $res;
}
}
if (!$filesonly) {
$res = $this->_rmDir($dir);
}
if (PEAR::isError($res)) {
return $res;
} else {
return true;
}
}
/**
* Lists up files and directories
*
* @param string $dir The directory to list up
*
* @access private
* @return array An array of dirs and files
*/
function _lsBoth($dir)
{
$list_splitted = $this->_listAndParse($dir);
if (PEAR::isError($list_splitted)) {
return $list_splitted;
}
if (!is_array($list_splitted["files"])) {
$list_splitted["files"] = array();
}
if (!is_array($list_splitted["dirs"])) {
$list_splitted["dirs"] = array();
}
$res = array();
@array_splice($res, 0, 0, $list_splitted["files"]);
@array_splice($res, 0, 0, $list_splitted["dirs"]);
return $res;
}
/**
* Lists up directories
*
* @param string $dir The directory to list up
*
* @access private
* @return array An array of dirs
*/
function _lsDirs($dir)
{
$list = $this->_listAndParse($dir);
if (PEAR::isError($list)) {
return $list;
}
return $list["dirs"];
}
/**
* Lists up files
*
* @param string $dir The directory to list up
*
* @access private
* @return array An array of files
*/
function _lsFiles($dir)
{
$list = $this->_listAndParse($dir);
if (PEAR::isError($list)) {
return $list;
}
return $list["files"];
}
/**
* This lists up the directory-content and parses the items into well-formated
* arrays.
* The results of this array are sorted (dirs on top, sorted by name;
* files below, sorted by name).
*
* @param string $dir The directory to parse
*
* @access private
* @return array Lists of dirs and files
* @see NET_FTP_ERR_RAWDIRLIST_FAILED
*/
function _listAndParse($dir)
{
$dirs_list = array();
$files_list = array();
$dir_list = @ftp_rawlist($this->_handle, $dir);
if (!is_array($dir_list)) {
return PEAR::raiseError('Could not get raw directory listing.',
NET_FTP_ERR_RAWDIRLIST_FAILED);
}
foreach ($dir_list AS $k=>$v) {
if (strncmp($v, 'total: ', 7) == 0 && preg_match('/total: \d+/', $v)) {
unset($dir_list[$k]);
break; // usually there is just one line like this
}
}
// Handle empty directories
if (count($dir_list) == 0) {
return array('dirs' => $dirs_list, 'files' => $files_list);
}
// Exception for some FTP servers seem to return this wiered result instead
// of an empty list
if (count($dirs_list) == 1 && $dirs_list[0] == 'total 0') {
return array('dirs' => array(), 'files' => $files_list);
}
if (!isset($this->_matcher) || PEAR::isError($this->_matcher)) {
$this->_matcher = $this->_determineOSMatch($dir_list);
if (PEAR::isError($this->_matcher)) {
return $this->_matcher;
}
}
foreach ($dir_list as $entry) {
$m = array();
if (!preg_match($this->_matcher['pattern'], $entry, $m)) {
continue;
}
$entry = array();
foreach ($this->_matcher['map'] as $key=>$val) {
$entry[$key] = $m[$val];
}
$entry['stamp'] = $this->_parseDate($entry['date']);
if ($entry['is_dir']) {
$dirs_list[] = $entry;
} else {
$files_list[] = $entry;
}
}
@usort($dirs_list, array("Net_FTP", "_natSort"));
@usort($files_list, array("Net_FTP", "_natSort"));
$res["dirs"] = (is_array($dirs_list)) ? $dirs_list : array();
$res["files"] = (is_array($files_list)) ? $files_list : array();
return $res;
}
/**
* Determine server OS
* This determines the server OS and returns a valid regex to parse
* ls() output.
*
* @param array &$dir_list The raw dir list to parse
*
* @access private
* @return mixed An array of 'pattern' and 'map' on success, otherwise
* PEAR::Error
* @see NET_FTP_ERR_DIRLIST_UNSUPPORTED
*/
function _determineOSMatch(&$dir_list)
{
foreach ($dir_list as $entry) {
foreach ($this->_ls_match as $match) {
if (preg_match($match['pattern'], $entry)) {
return $match;
}
}
}
$error = 'The list style of your server seems not to be supported. Please'.
'email a "$ftp->ls(NET_FTP_RAWLIST);" output plus info on the'.
'server to the maintainer of this package to get it supported!'.
'Thanks for your help!';
return PEAR::raiseError($error, NET_FTP_ERR_DIRLIST_UNSUPPORTED);
}
/**
* Lists a local directory
*
* @param string $dir_path The dir to list
*
* @access private
* @return array The list of dirs and files
*/
function _lsLocal($dir_path)
{
$dir = dir($dir_path);
$dir_list = array();
$file_list = array();
while (false !== ($entry = $dir->read())) {
if (($entry != '.') && ($entry != '..')) {
if (is_dir($dir_path.$entry)) {
$dir_list[] = $entry;
} else {
$file_list[] = $entry;
}
}
}
$dir->close();
$res['dirs'] = $dir_list;
$res['files'] = $file_list;
return $res;
}
/**
* Function for use with usort().
* Compares the list-array-elements by name.
*
* @param string $item_1 first item to be compared
* @param string $item_2 second item to be compared
*
* @access private
* @return int < 0 if $item_1 is less than $item_2, 0 if equal and > 0 otherwise
*/
function _natSort($item_1, $item_2)
{
return strnatcmp($item_1['name'], $item_2['name']);
}
/**
* Parse dates to timestamps
*
* @param string $date Date
*
* @access private
* @return int Timestamp
* @see NET_FTP_ERR_DATEFORMAT_FAILED
*/
function _parseDate($date)
{
// Sep 10 22:06 => Sep 10, 22:06
$res = array();
if (preg_match('/([A-Za-z]+)[ ]+([0-9]+)[ ]+([0-9]+):([0-9]+)/', $date,
$res)) {
$year = date('Y');
$month = $res[1];
$day = $res[2];
$hour = $res[3];
$minute = $res[4];
$date = "$month $day, $year $hour:$minute";
$tmpDate = strtotime($date);
if ($tmpDate > time()) {
$year--;
$date = "$month $day, $year $hour:$minute";
}
} elseif (preg_match('/^\d\d-\d\d-\d\d/', $date)) {
// 09-10-04 => 09/10/04
$date = str_replace('-', '/', $date);
}
$res = strtotime($date);
if (!$res) {
return $this->raiseError('Dateconversion failed.',
NET_FTP_ERR_DATEFORMAT_FAILED);
}
return $res;
}
}
?>
Net_FTP-1.4.0/Net/FTP/Observer.php 0000664 0001750 0001750 00000004706 12500046241 016023 0 ustar kguest kguest
* @author Laurent Laville
* @author Chuck Hagenbuch
* @copyright 1997-2008 The PHP Group
* @license BSD http://www.opensource.org/licenses/bsd-license.php
* @version CVS: $Id$
* @link http://pear.php.net/package/Net_FTP
* @since File available since Release 0.0.1
*/
/**
* This class implements the Observer part of a Subject-Observer
* design pattern. It listens to the events sent by a Net_FTP instance.
* This module had many influences from the Log_observer code.
*
* @category Networking
* @package FTP
* @author Laurent Laville
* @author Chuck Hagenbuch
* @author Tobias Schlitt
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.0
* @link http://pear.php.net/package/Net_FTP
* @since 1.3.0.0
* @access public
*
* @example observer_upload.php An example of Net_FTP_Observer implementation.
*/
class Net_FTP_Observer
{
/**
* Instance-specific unique identification number.
*
* @var integer
* @since 1.3.0
* @access private
*/
var $_id;
/**
* Creates a new basic Net_FTP_Observer instance.
*
* @since 1.3.0
* @access public
*/
function Net_FTP_Observer()
{
$this->_id = md5(microtime());
}
/**
* Returns the listener's identifier
*
* @return string The listener's identifier
* @since 1.3.0
* @access public
*/
function getId()
{
return $this->_id;
}
/**
* This is a stub method to make sure that Net_FTP_Observer classes do
* something when they are notified of a message. The default behavior
* is to just do nothing.
* You should override this method.
*
* @param mixed $event A hash describing the net event.
*
* @since 1.3.0
* @access public
* @return void
*/
function notify($event)
{
return;
}
}
?>
Net_FTP-1.4.0/Net/FTP/Socket.php 0000664 0001750 0001750 00000052556 12500046241 015472 0 ustar kguest kguest
* @copyright 1997-2008 The PHP Group
* @license BSD http://www.opensource.org/licenses/bsd-license.php
* @version CVS: $Id$
* @link http://pear.php.net/package/Net_FTP
* @since File available since Release 0.0.1
*/
/**
* Default FTP extension constants
*/
define('FTP_ASCII', 0);
define('FTP_TEXT', 0);
define('FTP_BINARY', 1);
define('FTP_IMAGE', 1);
define('FTP_TIMEOUT_SEC', 0);
/**
* What needs to be done overall?
* #1 Install the rest of these functions
* #2 Document better
* #3 Alot of other things I don't remember
*/
/*
* !!! NOTE !!!
* Most of the comment's are "not working",
* meaning they are not all up-to-date
* !!! NOTE !!!
*/
/**
* &resource ftp_connect ( string host [, int port [, int timeout ] ] );
*
* Opens an FTP connection and return resource or false on failure.
*
* FTP Success respons code: 220
*
* @param string $host Host to connect to
* @param int $port Optional, port to connect to
* @param int $timeout Optional, seconds until function timeouts
*
* @todo The FTP extension has ftp_get_option() function which returns the
* timeout variable. This function needs to be created and contain it as
* static variable.
* @todo The FTP extension has ftp_set_option() function which sets the
* timeout variable. This function needs to be created and called here.
* @access public
* @return &resource
*/
if (!function_exists('ftp_connect')) {
function &ftp_connect($host, $port = 21, $timeout = 90)
{
$false = false; // We are going to return refrence (E_STRICT)
if (!is_string($host) || !is_integer($port) || !is_integer($timeout)) {
return $false;
}
$iError = 0;
$sError = '';
$control = @fsockopen($host, $port, $iError, $sError,
$timeout);
$GLOBALS['_NET_FTP']['timeout'] = $timeout;
if (!is_resource($control)) {
return $false;
}
stream_set_blocking($control, true);
stream_set_timeout($control, $timeout);
do {
$content[] = fgets($control, 8129);
$array = socket_get_status($control);
} while ($array['unread_bytes'] > 0);
if (substr($content[count($content)-1], 0, 3) == 220) {
return $control;
}
return $false;
}
}
/**
* boolean ftp_login ( resource stream, string username, string password );
*
* Logs in to an given FTP connection stream.
* Returns TRUE on success or FALSE on failure.
*
* NOTE:
* Username and password are *not* optional. Function will *not*
* assume "anonymous" if username and/or password is empty
*
* FTP Success respons code: 230
*
* @param resource &$control FTP resource to login to
* @param string $username FTP Username to be used
* @param string $password FTP Password to be used
*
* @access public
* @return boolean
*/
if (!function_exists('ftp_login')) {
function ftp_login(&$control, $username, $password)
{
if (!is_resource($control) || is_null($username)) {
return false;
}
fputs($control, 'USER '.$username."\r\n");
$contents = array();
do {
$contents[] = fgets($control, 8192);
$array = socket_get_status($control);
} while ($array['unread_bytes'] > 0);
if (substr($contents[count($contents)-1], 0, 3) != 331) {
return false;
}
fputs($control, 'PASS '.$password."\r\n");
$contents = array();
do {
$contents[] = fgets($control, 8192);
$array = socket_get_status($control);
} while ($array['unread_bytes']);
if (substr($contents[count($contents)-1], 0, 3) == 230) {
return true;
}
trigger_error('ftp_login() [function.ftp-login'.
']: '.$contents[count($contents)-1], E_USER_WARNING);
return false;
}
}
/**
* boolean ftp_quit ( resource stream );
*
* Closes FTP connection.
* Returns TRUE or FALSE on error.
*
* NOTE: The PHP function ftp_quit is *alias* to ftp_close, here it is
* the *other-way-around* ( ftp_close() is alias to ftp_quit() ).
*
* NOTE:
* resource is set to null since unset() can't unset the variable.
*
* @param resource &$control FTP resource
*
* @access public
* @return boolean
*/
if (!function_exists('ftp_quit')) {
function ftp_quit(&$control)
{
if (!is_resource($control)) {
return false;
}
fputs($control, 'QUIT'."\r\n");
fclose($control);
$control = null;
return true;
}
}
/**
* Alias to ftp_quit()
*
* @param resource &$control FTP resource
*
* @see ftp_quit()
* @access public
* @return boolean
*/
if (!function_exists('ftp_close')) {
function ftp_close(&$control)
{
return ftp_quit($control);
}
}
/**
* string ftp_pwd ( resource stream );
*
* Gets the current directory name.
* Returns the current directory.
*
* Needs data connection: NO
* Success response code: 257
*
* @param resource &$control FTP resource
*
* @access public
* @return string
*/
if (!function_exists('ftp_pwd')) {
function ftp_pwd(&$control)
{
if (!is_resource($control)) {
return $control;
}
fputs($control, 'PWD'."\r\n");
$content = array();
do {
$content[] = fgets($control, 8192);
$array = socket_get_status($control);
} while ($array['unread_bytes'] > 0);
if (substr($cont = $content[count($content)-1], 0, 3) == 257) {
$pos = strpos($cont, '"')+1;
$pos2 = strrpos($cont, '"') - $pos;
$path = substr($cont, $pos, $pos2);
return $path;
}
return false;
}
}
/**
* boolean ftp_chdir ( resource stream, string directory );
*
* Changes the current directory to the specified directory.
* Returns TRUE on success or FALSE on failure.
*
* FTP success response code: 250
* Needs data connection: NO
*
* @param resource &$control FTP stream
* @param string $pwd Directory name
*
* @access public
* @return boolean
*/
if (!function_exists('ftp_chdir')) {
function ftp_chdir(&$control, $pwd)
{
if (!is_resource($control) || !is_string($pwd)) {
return false;
}
fputs($control, 'CWD '.$pwd."\r\n");
$content = array();
do {
$content[] = fgets($control, 8192);
$array = socket_get_status($control);
} while ($array['unread_bytes'] > 0);
if (substr($content[count($content)-1], 0, 3) == 250) {
return true;
}
trigger_error('ftp_chdir() [function.ftp-chdir]:
' .$content[count($content)-1], E_USER_WARNING);
return false;
}
}
$_NET_FTP = array();
$_NET_FTP['USE_PASSIVE'] = false;
$_NET_FTP['DATA'] = null;
/**
* boolean ftp_pasv ( resource stream, boolean passive );
*
* Toggles passive mode ON/OFF.
* Returns TRUE on success or FALSE on failure.
*
* Comment:
* Although my lack of C knowlege I checked how the PHP FTP extension
* do things here. Seems like they create the data connection and store
* it in object for other functions to use.
* This is now done here.
*
* FTP success response code: 227
*
* @param stream &$control FTP stream
* @param boolean $pasv True to switch to passive, false for active mode
*
* @access public
* @return boolean
*/
if (!function_exists('ftp_pasv')) {
function ftp_pasv(&$control, $pasv)
{
if (!is_resource($control) || !is_bool($pasv)) {
return false;
}
// If data connection exists, destroy it
if (isset($GLOBALS['_NET_FTP']['DATA'])) {
fclose($GLOBALS['_NET_FTP']['DATA']);
$GLOBALS['_NET_FTP']['DATA'] = null;
do {
fgets($control, 16);
$array = socket_get_status($control);
} while ($array['unread_bytes'] > 0);
}
// Are we suppost to create active or passive connection?
if (!$pasv) {
$GLOBALS['_NET_FTP']['USE_PASSIVE'] = false;
// Pick random "low bit"
$low = rand(39, 250);
// Pick random "high bit"
$high = rand(39, 250);
// Lowest possible port would be; 10023
// Highest possible port would be; 64246
$port = ($low<<8)+$high;
$ip = str_replace('.', ',', $_SERVER['SERVER_ADDR']);
$s = $ip.','.$low.','.$high;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (is_resource($socket)) {
if (socket_bind($socket, '0.0.0.0', $port)) {
if (socket_listen($socket)) {
$GLOBALS['_NET_FTP']['DATA'] = &$socket;
fputs($control, 'PORT '.$s."\r\n");
$line = fgets($control, 512);
if (substr($line, 0, 3) == 200) {
return true;
}
}
}
}
return false;
}
// Since we are here, we are suppost to create passive data connection.
fputs($control, 'PASV' ."\r\n");
$content = array();
do {
$content[] = fgets($control, 128);
$array = socket_get_status($control);
} while ($array['unread_bytes']);
if (substr($cont = $content[count($content)-1], 0, 3) != 227) {
return false;
}
$pos = strpos($cont, '(')+1;
$pos2 = strrpos($cont, ')')-$pos;
$string = substr($cont, $pos, $pos2);
$array = explode(',', $string);
// IP we are connecting to
$ip = $array[0]. '.' .$array[1]. '.' .$array[2]. '.' .$array[3];
// Port ( 256*lowbit + highbit
$port = ($array[4] << 8)+$array[5];
// Our data connection
$iError = 0;
$sError = '';
$data = fsockopen($ip, $port, $iError, $sError,
$GLOBALS['_NET_FTP']['timeout']);
if (is_resource($data)) {
$GLOBALS['_NET_FTP']['USE_PASSIVE'] = true;
$GLOBALS['_NET_FTP']['DATA'] = &$data;
stream_set_blocking($data, true);
stream_set_timeout($data, $GLOBALS['_NET_FTP']['timeout']);
return true;
}
return false;
}
}
/**
* array ftp_rawlist ( resource stream, string directory [,bool recursive] );
*
* Returns a detailed list of files in the given directory.
*
* Needs data connection: YES
*
* @param integer &$control FTP resource
* @param string $pwd Path to retrieve
* @param boolean $recursive Optional, retrieve recursive listing
*
* @todo Enable the recursive feature.
* @access public
* @return array
*/
if (!function_exists('ftp_rawlist')) {
function ftp_rawlist(&$control, $pwd, $recursive = false)
{
if (!is_resource($control) || !is_string($pwd)) {
return false;
}
if (!isset($GLOBALS['_NET_FTP']['DATA']) ||
!is_resource($GLOBALS['_NET_FTP']['DATA'])) {
ftp_pasv($control, $GLOBALS['_NET_FTP']['USE_PASSIVE']);
}
fputs($control, 'LIST '.$pwd."\r\n");
$msg = fgets($control, 512);
if (substr($msg, 0, 3) == 425) {
return false;
}
$data = &$GLOBALS['_NET_FTP']['DATA'];
if (!$GLOBALS['_NET_FTP']['USE_PASSIVE']) {
$data = &socket_accept($data);
}
$content = array();
switch ($GLOBALS['_NET_FTP']['USE_PASSIVE']) {
case true:
while (true) {
$string = rtrim(fgets($data, 1024));
if ($string=='') {
break;
}
$content[] = $string;
}
fclose($data);
break;
case false:
$string = socket_read($data, 1024, PHP_BINARY_READ);
$content = explode("\n", $string);
unset($content[count($content)-1]);
socket_close($GLOBALS['_NET_FTP']['DATA']);
socket_close($data);
break;
}
$data = $GLOBALS['_NET_FTP']['DATA'] = null;
fgets($control, 1024);
return $content;
}
}
/**
* string ftp_systype ( resource stream );
*
* Gets system type identifier of remote FTP server
* Returns the remote system type
*
* @param resource &$control FTP resource
*
* @access public
* @return string
*/
if (!function_exists('ftp_systype')) {
function ftp_systype(&$control)
{
if (!is_resource($control)) {
return false;
}
fputs($control, 'SYST'."\r\n");
$line = fgets($control, 256);
if (substr($line, 0, 3) != 215) {
return false;
}
$os = substr($line, 4, strpos($line, ' ', 4)-4);
return $os;
}
}
/**
* boolean ftp_alloc ( resource stream, integer bytes [, string &message ] );
*
* Allocates space for a file to be uploaded
* Return TRUE on success or FALSE on failure
*
* NOTE; Many FTP servers do not support this command and/or don't need it.
*
* FTP success respons key: Belive it's 200
* Needs data connection: NO
*
* @param resource &$control FTP stream
* @param integer $int Space to allocate
* @param string &$msg Optional, textual representation of the servers response
* will be returned by reference
*
* @access public
* @return boolean
*/
if (!function_exists('ftp_alloc')) {
function ftp_alloc(&$control, $int, &$msg = null)
{
if (!is_resource($control) || !is_integer($int)) {
return false;
}
fputs($control, 'ALLO '.$int.' R '.$int."\r\n");
$msg = rtrim(fgets($control, 256));
$code = substr($msg, 0, 3);
if ($code == 200 || $code == 202) {
return true;
}
return false;
}
}
/**
* bool ftp_put ( resource stream, string remote_file, string local_file,
* int mode [, int startpos ] );
*
* Uploads a file to the FTP server
* Returns TRUE on success or FALSE on failure.
*
* NOTE:
* The transfer mode specified must be either FTP_ASCII or FTP_BINARY.
*
* @param resource &$control FTP stream
* @param string $remote Remote file to write
* @param string $local Local file to upload
* @param integer $mode Upload mode, FTP_ASCI || FTP_BINARY
* @param integer $pos Optional, start upload at position
*
* @access public
* @return boolean
*/
if (!function_exists('ftp_put')) {
function ftp_put(&$control, $remote, $local, $mode, $pos = 0)
{
if (!is_resource($control) || !is_readable($local) ||
!is_integer($mode) || !is_integer($pos)) {
return false;
}
$types = array (
0 => 'A',
1 => 'I'
);
$windows = array (
0 => 't',
1 => 'b'
);
/**
* TYPE values:
* A ( ASCII )
* I ( BINARY )
* E ( EBCDIC )
* L ( BYTE )
*/
if (!isset($GLOBALS['_NET_FTP']['DATA']) ||
!is_resource($GLOBALS['_NET_FTP']['DATA'])) {
ftp_pasv($control, $GLOBALS['_NET_FTP']['USE_PASSIVE']);
}
// Establish data connection variable
$data = &$GLOBALS['_NET_FTP']['DATA'];
// Decide TYPE to use
fputs($control, 'TYPE '.$types[$mode]."\r\n");
$line = fgets($control, 256); // "Type set to TYPE"
if (substr($line, 0, 3) != 200) {
return false;
}
fputs($control, 'STOR '.$remote."\r\n");
sleep(1);
$line = fgets($control, 256); // "Opening TYPE mode data connect."
if (substr($line, 0, 3) != 150) {
return false;
}
// Creating resource to $local file
$fp = fopen($local, 'r'. $windows[$mode]);
if (!is_resource($fp)) {
$fp = null;
return false;
}
// Loop throu that file and echo it to the data socket
$i = 0;
switch ($GLOBALS['_NET_FTP']['USE_PASSIVE']) {
case false:
$data = &socket_accept($data);
while (!feof($fp)) {
$i += socket_write($data, fread($fp, 10240), 10240);
}
socket_close($data);
break;
case true:
while (!feof($fp)) {
$i += fputs($data, fread($fp, 10240), 10240);
}
fclose($data);
break;
}
$data = null;
do {
$line = fgets($control, 256);
} while (substr($line, 0, 4) != "226 ");
return true;
}
}
/**
* Retrieve a remote file to a local file
* Returns TRUE on success or FALSE on failure
*
* @param integer &$control Stream ID
* @param string $local Local filename
* @param string $remote Remote filename
* @param integer $mode Transfer mode (FTP_ASCII or FTP_BINARY)
* @param integer $resume Resume the file transfer or not
*
* @access public
* @return boolean
*/
if (!function_exists('ftp_get')) {
function ftp_get(&$control, $local, $remote, $mode, $resume = 0)
{
if (!is_resource($control) || !is_writable(dirname($local)) ||
!is_integer($mode) || !is_integer($resume)) {
return false;
}
$types = array (
0 => 'A',
1 => 'I'
);
$windows = array (
0 => 't',
1 => 'b'
);
if (!isset($GLOBALS['_NET_FTP']['DATA']) ||
!is_resource($GLOBALS['_NET_FTP'][ 'DATA'])) {
ftp_pasv($control, $GLOBALS['_NET_FTP']['USE_PASSIVE']);
}
fputs($control, 'TYPE '.$types[$mode]."\r\n");
$line = fgets($control, 256);
if (substr($line, 0, 3) != 200) {
return false;
}
$fp = fopen($local, 'w'.$windows[$mode]);
if (!is_resource($fp)) {
$fp = null;
return false;
}
return true;
}
}
/**
* Changes to the parent directory
* Returns TRUE on success or FALSE on failure
*
* @param integer &$control Stream ID
*
* @access public
* @return boolean
*/
if (!function_exists('ftp_cdup')) {
function ftp_cdup(&$control)
{
fputs($control, 'CDUP'."\r\n");
$line = fgets($control, 256);
if (substr($line, 0, 3) != 250) {
return false;
}
return true;
}
}
/**
* Set permissions on a file via FTP
* Returns the new file permission on success or false on error
*
* NOTE: This command is *not* supported by the standard
* NOTE: This command not ready!
*
* @param integer &$control Stream ID
* @param integer $mode Octal value
* @param string $file File to change permissions on
*
* @todo Figure out a way to chmod files via FTP
* @access public
* @return integer
*/
if (!function_exists('ftp_chmod')) {
function ftp_chmod(&$control, $mode, $file)
{
if (!is_resource($control) || !is_integer($mode) || !is_string($file)) {
return false;
}
// chmod not in the standard, proftpd doesn't recognize it
// use SITE CHMOD?
fputs($control, 'SITE CHMOD '.$mode. ' ' .$file."\r\n");
$line = fgets($control, 256);
if (substr($line, 0, 3) == 200) {
return $mode;
}
trigger_error('ftp_chmod() [function.ftp-chmod]: ' .
rtrim($line), E_USER_WARNING);
return false;
}
}
/**
* Deletes a file on the FTP server
* Returns TRUE on success or FALSE on failure
*
* @param integer &$control Stream ID
* @param string $path File to delete
*
* @access public
* @return boolean
*/
if (!function_exists('ftp_delete')) {
function ftp_delete(&$control, $path)
{
if (!is_resource($control) || !is_string($path)) {
return false;
}
fputs($control, 'DELE '.$path."\r\n");
$line = fgets($control, 256);
if (substr($line, 0, 3) == 250) {
return true;
}
return false;
}
}
/**
* Requests execution of a program on the FTP server
* NOTE; SITE EXEC is *not* supported by the standart
* Returns TRUE on success or FALSE on error
*
* @param integer &$control Stream ID
* @param string $cmd Command to send
*
* @access public
* @todo Look a littlebit better into this
* @return boolean
*/
if (!function_exists('ftp_exec')) {
function ftp_exec(&$control, $cmd)
{
if (!is_resource($control) || !is_string($cmd)) {
return false;
}
// Command not defined in the standart
// proftpd doesn't recognize SITE EXEC (only help,chgrp,chmod and ratio)
fputs($control, 'SITE EXEC '.$cmd."\r\n");
$line = fgets($control, 256);
// php.net/ftp_exec uses respons code 200 to verify if command was sent
// successfully or not, so we'll just do the same
if (substr($line, 0, 3) == 200) {
return true;
}
return false;
}
}
?>
Net_FTP-1.4.0/tests/AllTests.php 0000664 0001750 0001750 00000004125 12500046241 015745 0 ustar kguest kguest
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @link http://pear.php.net/package/Net_FTP
* @link http://www.phpunit.de PHPUnit
* @since File available since Release 0.0.1
*/
if (!defined('PHPUnit_MAIN_METHOD')) {
define('PHPUnit_MAIN_METHOD', 'Net_FTP_AllTests::main');
}
require_once 'PHPUnit/TextUI/TestRunner.php';
require_once 'Net_FTPTest.php';
/**
* Unit test case for Net_FTP
*
* @category Networking
* @package FTP
* @author Jorrit Schippers
* @copyright 1997-2008 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.4.0
* @link http://pear.php.net/package/Net_FTP
* @since Class available since Release 1.3.3
*/
class Net_FTP_AllTests
{
/**
* Main test suite run method
*
* @return void
*/
public static function main()
{
PHPUnit_TextUI_TestRunner::run(self::suite());
}
/**
* Main test suite method
*
* @return void
*/
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('Net_FTP Tests');
$suite->addTestSuite('Net_FTPTest');
return $suite;
}
}
if (PHPUnit_MAIN_METHOD == 'Net_FTP_AllTests::main') {
Net_FTP_AllTests::main();
}
?>
Net_FTP-1.4.0/tests/config.php.dist 0000664 0001750 0001750 00000000446 12500046241 016423 0 ustar kguest kguest