Index: wp-admin/includes/class-wp-filesystem-ssh2.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-ssh2.php	(revision 8812)
+++ wp-admin/includes/class-wp-filesystem-ssh2.php	(working copy)
@@ -9,6 +9,31 @@
 /**
  * WordPress Filesystem Class for implementing SSH2.
  *
+ * To use this class you must follow these steps for PHP 5.2.6+
+ * 
+ * @contrib http://kevin.vanzonneveld.net/techblog/article/make_ssh_connections_with_php/ - Installation Notes
+ * 
+ * Complie libssh2 (Note: Only 0.14 is officaly working with PHP 5.2.6+ right now.)
+ * 
+ * cd /usr/src
+ * wget http://surfnet.dl.sourceforge.net/sourceforge/libssh2/libssh2-0.14.tar.gz
+ * tar -zxvf libssh2-0.14.tar.gz
+ * cd libssh2-0.14/
+ * ./configure
+ * make all install
+ * 
+ * Note: No not leave the directory yet!
+ * 
+ * Enter: pecl install -f ssh2
+ * 
+ * Copy the ssh.so file it creates to your PHP Module Directory.
+ * Open up your PHP.INI file and look for where extensions are placed.
+ * Add in your PHP.ini file: extension=ssh2.so
+ * 
+ * Restart Apache!
+ * Check phpinfo() streams to confirm that: ssh2.shell, ssh2.exec, ssh2.tunnel, ssh2.scp, ssh2.sftp  exist.
+ * 
+ * 
  * @since 2.7
  * @package WordPress
  * @subpackage Filesystem
@@ -19,11 +44,18 @@
 	var $debugtest = true;	//	this is my var that will output the text when debuggin this class
 	
 	var $link;
-	var $timeout = 5;
+	/*
+	 * This is the timeout value for ssh results to comeback. 
+	 * Slower servers might need this incressed, but this number otherwise should not change.
+	 * 
+	 * @parm $timeout int
+	 * 
+	 */
+	var $timeout = 15;
 	var $errors = array();
 	var $options = array();
 
-	var $permission = null;
+	var $permission = 0644;
 
 	var $filetypes = array(
 							'php'=>FTP_ASCII,
@@ -71,7 +103,7 @@
 			$this->options['username'] = $opt['username'];
 
 		if ( empty ($opt['password']) )
-			$this->errors->add('empty_password', __('SSH password is required'));
+			$this->errors->add('empty_password', __('SSH2 password is required'));
 		else
 			$this->options['password'] = $opt['password'];
 
@@ -95,49 +127,58 @@
 	}
 	
 	function run_command($link, $command, $returnbool = false) {
-		$this->debug("run_command(".$command.");");
-		if(!($stream = @ssh2_exec( $link, $command ))) {
+		//$this->debug("run_command(".$command.",".$returnbool.");");
+		if(!($stream = @ssh2_exec( $link, $command . "; echo \"__COMMAND_FINISHED__\";"))) {
             $this->errors->add('command', sprintf(__('Unable to preform command: %s'), $command));
         } else {
             stream_set_blocking( $stream, true );
 			$time_start = time();
-            $data = "";
+            $data = null;
 			while( true ) {
+			    if (strpos($data,"__COMMAND_FINISHED__") !== false){
+			        break;	//	the command has finshed!
+			    }
 			    if( (time()-$time_start) > $this->timeout ){
 			    	$this->errors->add('command', sprintf(__('Connection to the server has timeout after %s seconds.'), $this->timeout));
-			        break;
+					unset($this->link);	//	close connection
+			        return false;
 			    }
 	            while( $buf = fread( $stream, strlen($stream) ) ){
 	                $data .= $buf;
 	            }
 			}
             fclose($stream);
-            if (($returnbool) && ($data)) {
-            	$this->debug("Data: " . print_r($data, true) . " Returning: True");
+			$data = str_replace("__COMMAND_FINISHED__", "", $data);
+			//$this->debug("run_command(".$command."); --> \$data = " . $data);
+            if (($returnbool) && ( (int) $data )) {
+            	$this->debug("Data. Returning: True");
             	return true;
-            } elseif (($returnbool) && (!$data)) {
-            	$this->debug("Data: " . print_r($data, true) . " Returning: False");
+            } elseif (($returnbool) && (! (int) $data )) {
+            	$this->debug("Data. Returning: False");
             	return false;
             } else {
-            	$this->debug("Data: " . print_r($data, true));
+            	$this->debug("Data Only.");
             	return $data;
             }
         }
+		return false;
 	}
 
 	function debug($text)
 	{
 		if ($this->debugtest)
 		{
-			echo $text . "<br/>";
+			echo "<br/>" . $text . "<br/>";
 		}
 	}
 
 	function setDefaultPermissions($perm) {
+		$this->debug("setDefaultPermissions();");
 		$this->permission = $perm;
 	}
 
-	function get_contents($file, $type = '', $resumepos = 0 ){
+	function get_contents($file, $type = '', $resumepos = 0 ) {
+		$this->debug("get_contents();");
 		if( empty($type) ){
 			$extension = substr(strrchr($file, "."), 1);
 			$type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_ASCII;
@@ -157,25 +198,30 @@
 	}
 	
 	function get_contents_array($file) {
+		$this->debug("get_contents_array();");
 		return explode("\n", $this->get_contents($file));
 	}
 	
 	function put_contents($file, $contents, $type = '' ) {
+		$this->debug("put_contents(".$file.",contents,".$type.");");
 		if( empty($type) ) {
 			$extension = substr(strrchr($file, "."), 1);
 			$type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_ASCII;
 		}
 		$temp = tmpfile();
-		if ( ! $temp )
+		if ( ! $temp ) {
 			return false;
+		}
 		fwrite($temp, $contents);
 		fseek($temp, 0); //Skip back to the start of the file being written to
-		$ret = @ssh2_scp_send($this->link, $file, $temp, $type);
+		// @todo: fix me
+		$ret = @ssh2_scp_send($this->link, $temp, $file, 0644);
 		fclose($temp);
 		return $ret;
 	}
 	
 	function cwd() {
+//		$this->debug("cwd();");
 		$cwd = $this->run_command($this->link, "pwd");
 		if( $cwd )
 			$cwd = trailingslashit($cwd);
@@ -183,6 +229,7 @@
 	}
 	
 	function chdir($dir) {
+//		$this->debug("chdir();");
 		if ($this->run_command($this->link, "cd " . $dir, true)) {
 			return true;
 		}
@@ -190,10 +237,12 @@
 	}
 	
 	function chgrp($file, $group, $recursive = false ) {
+		$this->debug("chgrp();");
 		return false;
 	}
 	
 	function chmod($file, $mode = false, $recursive = false) {
+		$this->debug("chmod();");
 		if( ! $mode )
 			$mode = $this->permission;
 		if( ! $mode )
@@ -212,25 +261,30 @@
 	}
 	
 	function chown($file, $owner, $recursive = false ) {
+		$this->debug("chown();");
 		return false;
 	}
 	
 	function owner($file) {
+		$this->debug("owner();");
 		$dir = $this->dirlist($file);
 		return $dir[$file]['owner'];
 	}
 	
 	function getchmod($file) {
+		$this->debug("getchmod();");
 		$dir = $this->dirlist($file);
 		return $dir[$file]['permsn'];
 	}
 	
 	function group($file) {
+		$this->debug("group();");
 		$dir = $this->dirlist($file);
 		return $dir[$file]['group'];
 	}
 	
 	function copy($source, $destination, $overwrite = false ) {
+		$this->debug("copy();");
 		if( ! $overwrite && $this->exists($destination) )
 			return false;
 		$content = $this->get_contents($source);
@@ -240,22 +294,24 @@
 	}
 	
 	function move($source, $destination, $overwrite = false) {
+		$this->debug("move();");
 		return @ssh2_sftp_rename($this->link, $source, $destination);
 	}
 
-	function delete($file, $recursive=false) {
-		if ( $this->is_file($file) )
-			return @ssh2_sftp_unlink($this->link, $file);
-		if ( !$recursive )
-			return @ssh2_sftp_rmdir($this->link, $file);
-		$filelist = $this->dirlist($file);
-		foreach ((array) $filelist as $filename => $fileinfo) {
-			$this->delete($file . '/' . $filename, $recursive);
+	function delete($path, $recursive = false) {
+		$this->debug("delete(".$path.");");
+		$sftp = ssh2_sftp($this->link);
+		if ($recursive) {
+			$this->debug("Delete Directory: " . $path);
+			return @ssh2_sftp_rmdir($sftp, $path);
+		} else {
+			$this->debug("Delete File " . $path);
+			return @ssh2_sftp_unlink($sftp, $path);
 		}
-		return @ssh2_sftp_rmdir($this->link, $file);
 	}
 
 	function exists($file) {
+		$this->debug("exists();");
 		$list = $this->run_command($this->link, sprintf('ls -la %s', $file));
 		if( ! $list )
 			return false;
@@ -263,61 +319,74 @@
 	}
 	
 	function is_file($file) {
-		return $this->is_dir($file) ? false : true;
+		return $this->is_dir($file) ? true : false;
 	}
 	
 	function is_dir($path) {
 		$cwd = $this->cwd();
-		$result = $this->run_command($this->link, sprintf('cd %s', $path), true);
-		if( $result && $path == $this->cwd() || $this->cwd() != $cwd ) {
-			// @todo: use ssh2_exec
-			@ftp_chdir($this->link, $cwd);
+		$result = $this->run_command($this->link, "cd " . $path, true);
+		if ( $result && $path == $this->cwd() || $this->cwd() != $cwd ) {
+			$this->run_command($this->link, sprintf('cd %s', $path), true);
 			return true;
 		}
 		return false;
 	}
 	
 	function is_readable($file) {
+		$this->debug("is_readable();");
 		//Get dir list, Check if the file is writable by the current user??
 		return true;
 	}
 	
 	function is_writable($file) {
+		$this->debug("is_writable();");
 		//Get dir list, Check if the file is writable by the current user??
 		return true;
 	}
 	
 	function atime($file) {
+		$this->debug("atime();");
 		return false;
 	}
 	
 	function mtime($file) {
+		$this->debug("mtime();");
 		return;	//	i have to look up to see if there is a way in SSH2 to look the modifed date
 		//	return ftp_mdtm($this->link, $file);
 	}
 	
 	function size($file) {
+		$this->debug("size();");
 		return;	//	i have to look up to see if there is a way in SSH2 to get the file size
 		//	return ftp_size($this->link, $file);
 	}
 	
 	function touch($file, $time = 0, $atime = 0) {
+		$this->debug("touch();");
 		return false;
 	}
 	
-	function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
-		if( !@ssh2_sftp_mkdir($this->link, $path) )
+	function mkdir($path, $octal = 0755) {
+		$this->debug("mkdir(".$path.",".$octal.");");
+		$sftp = ssh2_sftp($this->link);
+		if (!function_exists('ssh2_sftp_mkdir')) {
+			$this->errors->add('function_needed_mkdir', sprintf(__('Your SSH2 Module does not support ssh2_sftp_mkdir')));
+		}
+		if( !@ssh2_sftp_mkdir($sftp, $path, $octal, true) && !is_dir($path . "/") ) {
+			$this->debug("Directory not created.");
 			return false;
-		if( $chmod )
-			$this->chmod($path, $chmod);
-		if( $chown )
-			$this->chown($path, $chown);
-		if( $chgrp )
-			$this->chgrp($path, $chgrp);
-		return true;
+		} else {
+			$this->debug("Directory created.");
+			return true;
+		}
 	}
 	
 	function rmdir($path, $recursive = false) {
+		$this->debug("rmdir(".$path.",".$recursive."); --> Note: Recursive does not work like MKDIR");
+		$sftp = ssh2_sftp($this->link);
+		if (!function_exists('ssh2_sftp_rmdir')) {
+			$this->errors->add('function_needed_rmdir', sprintf(__('Your SSH2 Module does not support ssh2_sftp_rmdir')));
+		}
 		if( ! $recursive )
 			return @ssh2_sftp_rmdir($this->link, $path);
 
@@ -328,6 +397,7 @@
 	}
 
 	function parselisting($line) {
+	$this->debug("parselisting();");
 		$is_windows = ($this->OS_remote == FTP_OS_Windows);
 		if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/", $line, $lucifer)) {
 			$b = array();
@@ -390,6 +460,7 @@
 	}
 
 	function dirlist($path = '.', $incdot = false, $recursive = false) {
+		$this->debug("dirlist();");
 		if( $this->is_file($path) ) {
 			$limitFile = basename($path);
 			$path = dirname($path) . '/';
@@ -442,10 +513,10 @@
 		return $ret;
 	}
 
-	function __destruct(){
-		if( $this->link )
-			unset($this->link);
+	function __destruct() {
+		if ( ( $this->link ) || ( $this->linksftp ) )
+			unset($this->link, $this->linksftp);
 	}
 }
 
-?>
\ No newline at end of file
+?>
Index: wp-admin/includes/file.php
===================================================================
--- wp-admin/includes/file.php	(revision 8812)
+++ wp-admin/includes/file.php	(working copy)
@@ -389,32 +389,36 @@
 	$to = trailingslashit($to);
 	$path = explode('/', $to);
 	$tmppath = '';
+	
 	for ( $j = 0; $j < count($path) - 1; $j++ ) {
-		$tmppath .= $path[$j] . '/';
-		if ( ! $fs->is_dir($tmppath) )
-			$fs->mkdir($tmppath, 0755);
+		$tmppath .= $path[$j] . '/';	// for ssh, you can enter the whole directory stucture and it will create the folders as needed. unsure about ftp/ftps
 	}
 
+	if ( ! $fs->is_dir($tmppath) ) {
+		if ( $fs->method == "ssh2" ) { $tmppath = untrailingslashit($tmppath); }	//	ssh can not take the trailing slash
+		$fs->mkdir($tmppath, 0755);
+	}
+
 	foreach ($archive_files as $file) {
 		$path = explode('/', $file['filename']);
 		$tmppath = '';
-
 		// Loop through each of the items and check that the folder exists.
 		for ( $j = 0; $j < count($path) - 1; $j++ ) {
 			$tmppath .= $path[$j] . '/';
 			if ( ! $fs->is_dir($to . $tmppath) )
+				if ( $fs->method == "ssh2" ) { $tmppath = untrailingslashit($tmppath); }	//	ssh can not take the trailing slash
 				if ( !$fs->mkdir($to . $tmppath, 0755) )
 					return new WP_Error('mkdir_failed', __('Could not create directory'), $to . $tmppath);
 		}
 
 		// We've made sure the folders are there, so let's extract the file now:
 		if ( ! $file['folder'] ) {
-			if ( !$fs->put_contents( $to . $file['filename'], $file['content']) )
+			if ( !$fs->put_contents( $to . $file['filename'], $file['content']) )	//	for ssh, this is where it is currenly failing.
 				return new WP_Error('copy_failed', __('Could not copy file'), $to . $file['filename']);
 			$fs->chmod($to . $file['filename'], 0644);
 		}
 	}
-
+	
 	return true;
 }
 
@@ -480,10 +484,7 @@
 		unlink($temp_file);
 	}
 
-	if ( isset($args['connection_type']) && 'ssh' == $args['connection_type'] ) {
-		$method = 'SSH2';
-		return apply_filters('filesystem_method', $method);
-	}
+	if ( ! $method && isset($args['connection_type']) && 'ssh' == $args['connection_type'] && extension_loaded('ssh2') ) $method = 'ssh2';
 
 	if ( ! $method && extension_loaded('ftp') ) $method = 'ftpext';
 	if ( ! $method && ( extension_loaded('sockets') || function_exists('fsockopen') ) ) $method = 'ftpsockets'; //Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread
@@ -551,6 +552,10 @@
 <td><input name="password" type="password" id="password" value=""<?php if( defined('FTP_PASS') ) echo ' disabled="disabled"' ?> size="40" /><?php if( defined('FTP_PASS') && !empty($password) ) echo '<em>'.__('(Password not shown)').'</em>'; ?></td>
 </tr>
 <tr valign="top">
+<th scope="row"><label for="port"><?php _e('Port') ?></label></th>
+<td><input name="port" type="port" id="port" value="21"<?php if( defined('FTP_PORT') ) echo ' disabled="disabled"' ?> size="5" /></td>
+</tr>
+<tr valign="top">
 <th scope="row"><?php _e('Connection Type') ?></th>
 <td>
 <fieldset><legend class="hidden"><?php _e('Connection Type') ?> </legend>
Index: wp-admin/includes/update.php
===================================================================
--- wp-admin/includes/update.php	(revision 8812)
+++ wp-admin/includes/update.php	(working copy)
@@ -238,23 +238,25 @@
 		return new WP_Error('download_failed', __('Download failed.'), $download_file->get_error_message());
 
 	$working_dir = $content_dir . 'upgrade/core';
-
 	// Clean up working directory
-	if ( $wp_filesystem->is_dir($working_dir) )
+	if ( $wp_filesystem->is_dir($working_dir) ) {
 		$wp_filesystem->delete($working_dir, true);
+	}
 
-	apply_filters('update_feedback', __('Unpacking the update'));
+	apply_filters('update_feedback', __('Unpacking the core update'));
 	// Unzip package to working directory
-	$result = unzip_file($download_file, $working_dir);
-
+	// @note: It fails here -- Shane
+	$result = unzip_file($download_file, $working_dir);	//	this is the main problem
 	// Once extracted, delete the package
 	unlink($download_file);
-
+	
 	if ( is_wp_error($result) ) {
+		$wp_filesystem->debug("Error with the unzip.");	
 		$wp_filesystem->delete($working_dir, true);
+		exit;	// having problem with the delete also...
 		return $result;
 	}
-
+	
 	// Copy update-core.php from the new version into place.
 	if ( !$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true) ) {
 		$wp_filesystem->delete($working_dir, true);
