<?php
class saxueftp extends saxueobject {
		public $_host;
		public $_port = 21;
		public $_user;
		public $_pass;
		public $_path = ".";
		public $_ssl = 0;
		public $_timeout = 0;
		public $_pasv = 1;
		public $connid;
		static public $instance = array();

		public function wipespecial( $_str ) {
				return str_replace( array( "\n", "\r" ), "", $_str );
		} 

		public function saxueftp( $_ftphost = "", $_ftpuser = "", $_ftppass = "", $_ftppath = ".", $_ftpport = 21, $_timeout = 0, $_ftpssl = 0, $_ftppasv = 1 ) {
				$this -> _host = $this -> wipespecial( $_ftphost );
				$this -> _user = $_ftpuser;
				$this -> _pass = $_ftppass;
				$this -> _port = intval( $_ftpport );
				$this -> _timeout = intval( $_timeout );
				$this -> _ssl = intval( $_ftpssl );
				$this -> _pasv = intval( $_ftppasv );
				$this -> _path = $_ftppath;
		} 

		public function retinstance() {
				return self :: $instance;
		} 

		public function close( $_ftp = null ) {
				if ( is_object( $_ftp ) ) {
						$_ftp -> ftp_close();
				} else if ( !empty( self :: $instance ) ) {
						foreach ( self :: $instance as $_ftp ) {
								$_ftp -> ftp_close();
						} 
				} 
		} 

		public function getinstance( $_ftphost = "", $_ftpuser = "", $_ftppass = "", $_ftppath = ".", $_ftpport = 21, $_timeout = 0, $_ftpssl = 0, $_ftppasv = 1 ) {
				$inskey = md5( $_ftphost . "," . $_ftpuser . "," . $_ftppass . "," . $_ftppath . "," . $_ftpport . "," . $_timeout . "," . $_ftpssl . "," . $_ftppasv );
				if ( !isset( self :: $instance[$inskey] ) ) {
						self :: $instance[$inskey] = new saxueftp( $_ftphost, $_ftpuser, $_ftppass, $_ftppath, $_ftpport, $_timeout, $_ftpssl, $_ftppasv );
						$fid = self :: $instance[$inskey] -> ftp_connect();
						if ( $fid !== 1 ) {
								return false;
						} 
				} 
				return self :: $instance[$inskey];
		} 

		public function ftp_connect() {
				$func = $this -> _ssl && function_exists( "ftp_ssl_connect" ) ? "ftp_ssl_connect" : "ftp_connect";
				if ( $func == "ftp_connect" && !function_exists( "ftp_connect" ) ) {
						$this -> raiseerror( "FTP not supported", SAXUE_ERROR_RETURN );
						return -4;
				} 
				if ( $this -> connid = @$func( $this -> _host, $this -> _port, 20 ) ) {
						if ( $this -> _timeout && function_exists( "ftp_set_option" ) ) {
								@ftp_set_option( $this -> connid, FTP_TIMEOUT_SEC, $this -> _timeout );
						} 
						if ( $this -> ftp_login( $this -> _user, $this -> _pass ) ) {
								if ( $this -> _pasv ) {
										$this -> ftp_pasv( true );
								} 
								if ( $this -> ftp_chdir( $this -> _path ) ) {
										if ( !defined( "SAXUE_FTP_CONNECTED" ) ) {
												@define( "SAXUE_FTP_CONNECTED", true );
										} 
										return 1;
								} else {
										$this -> ftp_close();
										$this -> raiseerror( "Chdir " . $this -> _path . " error", SAXUE_ERROR_RETURN );
										return -3;
								}
						} else {
								$this -> ftp_close();
								$this -> raiseerror( "FTP login failure", SAXUE_ERROR_RETURN );
								return -2;
						}
				} else {
						$this -> raiseerror( "Couldn't connect to " . $this -> _host . ":" . $this -> _port, SAXUE_ERROR_RETURN );
						return -2;
				}
		} 

		public function ftp_mkdir( $_remotedir ) {
				$_remotedir = $this -> wipespecial( $_remotedir );
				return @ftp_mkdir( $this -> connid, $_remotedir );
		} 

		public function ftp_rmdir( $_remotedir ) {
				$_remotedir = $this -> wipespecial( $_remotedir );
				return @ftp_rmdir( $this -> connid, $_remotedir );
		} 

		public function ftp_put( $_remotefile, $_localfile, $_mode = FTP_BINARY, $_resume = 0 ) {
				$_remotefile = $this -> wipespecial( $_remotefile );
				$_localfile = $this -> wipespecial( $_localfile );
				$_mode = intval( $_mode );
				$_resume = intval( $_resume );
				return @ftp_put( $this -> connid, $_remotefile, $_localfile, $_mode, $_resume );
		} 

		public function ftp_size( $_remotefile ) {
				$_remotefile = $this -> wipespecial( $_remotefile );
				return @ftp_size( $this -> connid, $_remotefile );
		} 

		public function ftp_close() {
				return @ftp_close( $this -> connid );
		} 

		public function ftp_delete( $_path ) {
				$_path = $this -> wipespecial( $_path );
				return @ftp_delete( $this -> connid, $_path );
		} 

		public function ftp_get( $_localfile, $_remotefile, $_mode = FTP_BINARY, $_resume = 0 ) {
				$_remotefile = $this -> wipespecial( $_remotefile );
				$_localfile = $this -> wipespecial( $_localfile );
				$_mode = intval( $_mode );
				$_resume = intval( $_resume );
				return @ftp_get( $this -> connid, $_localfile, $_remotefile, $_mode, $_resume );
		} 

		public function ftp_login( $_ftpusername, $_ftppassword ) {
				$_ftpusername = $this -> wipespecial( $_ftpusername );
				$_ftppassword = str_replace( array( "\n", "\r" ), array( "", "" ), $_ftppassword );
				return @ftp_login( $this -> connid, $_ftpusername, $_ftppassword );
		} 

		public function ftp_pasv( $_pasv ) {
				$_pasv = intval( $_pasv );
				return @ftp_pasv( $this -> connid, $_pasv );
		} 

		public function ftp_chdir( $_remotedir ) {
				$_remotedir = $this -> wipespecial( $_remotedir );
				return @ftp_chdir( $this -> connid, $_remotedir );
		} 

		public function ftp_site( $_cmd ) {
				$_cmd = $this -> wipespecial( $_cmd );
				return @ftp_site( $this -> connid, $_cmd );
		} 

		public function ftp_chmod( $_mode, $_filename ) {
				$_mode = intval( $_mode );
				$_filename = $this -> wipespecial( $_filename );
				if ( function_exists( "ftp_chmod" ) ) {
						return @ftp_chmod( $this -> connid, $_mode, $_filename );
				} 
				return $this -> ftp_site( $this -> connid, "CHMOD " . $_mode . " " . $_filename );
		} 

		public function ftp_rename( $_fromname, $_toname ) {
				return @ftp_rename( $this -> connid, $_fromname, $_toname );
		} 

		public function ftp_pwd() {
				return @ftp_pwd( $this -> connid );
		} 

		public function ftp_nlist( $_path ) {
				$_path = $this -> wipespecial( $_path );
				return @ftp_nlist( $this -> connid, $_path );
		} 

		public function ftp_rawlist( $_path ) {
				$_path = $this -> wipespecial( $_path );
				return @ftp_rawlist( $this -> connid, $_path );
		}

		public function ftp_delfolder( $_path, $_flag = true ) {
				$_path = $this -> wipespecial( $_path );
				if ( $_flag ) {
						$_ret = $this -> ftp_rmdir( $_path ) || $this -> ftp_delete( $_path );
				} else {
						$_ret = false;
				} 
				if ( !$_ret ) {
						$_files = $this -> ftp_nlist( $_path );
						foreach ( $_files as $_values ) {
								$_values = basename( $_values );
								if ( !$this -> ftp_delete( $_path . "/" . $_values ) ) {
										$this -> ftp_delfolder( $_path . "/" . $_values, true );
								} 
						} 
						if ( $_flag ) {
								return $this -> ftp_rmdir( $_path );
						} else {
								return true;
						}
				} else {
						return $_ret;
				}
		} 

		public function ftp_mkdirs( $_path ) {
				$_path = $this -> wipespecial( $_path );
				$_subdirarr = explode( "/", $_path );
				$_subdirnum = count( $_subdirarr );
				foreach ( $_subdirarr as $_val ) {
						if ( $this -> ftp_chdir( $_val ) == false ) {
								$_tmp = $this -> ftp_mkdir( $_val );
								if ( $_tmp == false ) {
										$this -> raiseerror( "FTP mkdir failure", SAXUE_ERROR_RETURN );
										exit();
								} 
								$this -> ftp_chdir( $_val );
						} 
				} 
				for ( $_i = 1; $_i <= $_subdirnum; ++$_i ) {
						@ftp_cdup( $this -> connid );
				} 
		} 

		public function ftp_xcopy( $_fromdir, $_todir ) {
				$_fromdir = $this -> wipespecial( $_fromdir );
				$_todir = $this -> wipespecial( $_todir );
				$_listdir = $this -> ftp_nlist( $_fromdir );
				$this -> ftp_mkdirs( $_todir );
				foreach ( $_listdir as $_subdir ) {
						$_subdir = basename( $_subdir );
						if ( !$this -> ftp_rename( $_fromdir . "/" . $_subdir, $_todir . "/" . $_subdir ) ) {
								$this -> ftp_mkdir( $_todir . "/" . $_subdir );
								$this -> ftp_xcopy( $_fromdir . "/" . $_subdir, $_todir . "/" . $_subdir );
						} 
				} 
		} 
} 
