Index: wp-admin/includes/class-wp-filesystem-base.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-base.php	(revision 10899)
+++ wp-admin/includes/class-wp-filesystem-base.php	(working copy)
@@ -46,8 +46,6 @@
 	 * @return string The location of the remote path.
 	 */
 	function abspath() {
-		if ( defined('FTP_BASE') && strpos($this->method, 'ftp') !== false )
-			return FTP_BASE;
 		$folder = $this->find_folder(ABSPATH);
 		//Perhaps the FTP folder is rooted at the WordPress install, Check for wp-includes folder in root, Could have some false positives, but rare.
 		if ( ! $folder && $this->is_dir('/wp-includes') )
@@ -62,8 +60,6 @@
 	 * @return string The location of the remote path.
 	 */
 	function wp_content_dir() {
-		if ( defined('FTP_CONTENT_DIR') && strpos($this->method, 'ftp') !== false )
-			return FTP_CONTENT_DIR;
 		return $this->find_folder(WP_CONTENT_DIR);
 	}
 	/**
@@ -75,8 +71,6 @@
 	 * @return string The location of the remote path.
 	 */
 	function wp_plugins_dir() {
-		if ( defined('FTP_PLUGIN_DIR') && strpos($this->method, 'ftp') !== false )
-			return FTP_PLUGIN_DIR;
 		return $this->find_folder(WP_PLUGIN_DIR);
 	}
 	/**
@@ -142,6 +136,15 @@
 	 */
 	function find_folder($folder) {
 
+		if ( strpos($this->method, 'ftp') !== false ) {
+			$constant_overrides = array( 'FTP_BASE' => ABSPATH, 'FTP_CONTENT_DIR' => WP_CONTENT_DIR, 'FTP_PLUGIN_DIR' => WP_PLUGIN_DIR );
+			foreach ( $constant_overrides as $constant => $dir )
+				if ( defined($constant) && $folder === $dir )
+					return trailingslashit(constant($constant));
+		} elseif ( 'direct' == $this->method ) {
+			return trailingslashit($folder);
+		}
+
 		$folder = preg_replace('|^([a-z]{1}):|i', '', $folder); //Strip out windows driveletter if its there.
 		$folder = str_replace('\\', '/', $folder); //Windows path sanitiation
 
@@ -149,6 +152,7 @@
 			return $this->cache[ $folder ];
 
 		if ( $this->exists($folder) ) { //Folder exists at that absolute path.
+			$folder = trailingslashit($folder);
 			$this->cache[ $folder ] = $folder;
 			return $folder;
 		}
@@ -189,23 +193,23 @@
 			// If its found, change into it and follow through looking for it.
 			// If it cant find WordPress down that route, it'll continue onto the next folder level, and see if that matches, and so on.
 			// If it reaches the end, and still cant find it, it'll return false for the entire function.
-			if( isset($files[ $key ]) ){
+			if ( isset($files[ $key ]) ){
 				//Lets try that folder:
 				$newdir = trailingslashit(path_join($base, $key));
-				if( $this->verbose )
+				if ( $this->verbose )
 					printf( __('Changing to %s') . '<br/>', $newdir );
-				if( $ret = $this->search_for_folder( $folder, $newdir, $loop) )
+				if ( $ret = $this->search_for_folder( $folder, $newdir, $loop) )
 					return $ret;
 			}
 		}
 
 		//Only check this as a last resort, to prevent locating the incorrect install. All above proceeedures will fail quickly if this is the right branch to take.
-		if(isset( $files[ $last_path ] ) ) {
-			if( $this->verbose )
+		if (isset( $files[ $last_path ] ) ) {
+			if ( $this->verbose )
 				printf( __('Found %s') . '<br/>',  $base . $last_path );
-			return $base . $last_path;
+			return trailingslashit($base . $last_path);
 		}
-		if( $loop )
+		if ( $loop )
 			return false;//Prevent tihs function looping again.
 		//As an extra last resort, Change back to / if the folder wasnt found. This comes into effect when the CWD is /home/user/ but WP is at /var/www/.... mainly dedicated setups.
 		return $this->search_for_folder($folder, '/', true);
Index: wp-admin/includes/class-wp-filesystem-direct.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-direct.php	(revision 10899)
+++ wp-admin/includes/class-wp-filesystem-direct.php	(working copy)
@@ -14,9 +14,9 @@
  * @subpackage Filesystem
  * @uses WP_Filesystem_Base Extends class
  */
-class WP_Filesystem_Direct  extends WP_Filesystem_Base {
+class WP_Filesystem_Direct extends WP_Filesystem_Base {
 	var $permission = null;
-	var $errors = array();
+	var $errors = null;
 	function WP_Filesystem_Direct($arg) {
 		$this->method = 'direct';
 		$this->errors = new WP_Error();
@@ -49,82 +49,82 @@
 		return @chdir($dir);
 	}
 	function chgrp($file, $group, $recursive = false) {
-		if( ! $this->exists($file) )
+		if ( ! $this->exists($file) )
 			return false;
-		if( ! $recursive )
+		if ( ! $recursive )
 			return @chgrp($file, $group);
-		if( ! $this->is_dir($file) )
+		if ( ! $this->is_dir($file) )
 			return @chgrp($file, $group);
 		//Is a directory, and we want recursive
 		$file = trailingslashit($file);
 		$filelist = $this->dirlist($file);
-		foreach($filelist as $filename)
+		foreach ($filelist as $filename)
 			$this->chgrp($file . $filename, $group, $recursive);
 
 		return true;
 	}
 	function chmod($file, $mode = false, $recursive = false) {
-		if( ! $mode )
+		if ( ! $mode )
 			$mode = $this->permission;
-		if( ! $this->exists($file) )
+		if ( ! $this->exists($file) )
 			return false;
-		if( ! $recursive )
+		if ( ! $recursive )
 			return @chmod($file,$mode);
-		if( ! $this->is_dir($file) )
+		if ( ! $this->is_dir($file) )
 			return @chmod($file, $mode);
 		//Is a directory, and we want recursive
 		$file = trailingslashit($file);
 		$filelist = $this->dirlist($file);
-		foreach($filelist as $filename)
+		foreach ($filelist as $filename)
 			$this->chmod($file . $filename, $mode, $recursive);
 
 		return true;
 	}
 	function chown($file, $owner, $recursive = false) {
-		if( ! $this->exists($file) )
+		if ( ! $this->exists($file) )
 			return false;
-		if( ! $recursive )
+		if ( ! $recursive )
 			return @chown($file, $owner);
-		if( ! $this->is_dir($file) )
+		if ( ! $this->is_dir($file) )
 			return @chown($file, $owner);
 		//Is a directory, and we want recursive
 		$filelist = $this->dirlist($file);
-		foreach($filelist as $filename){
+		foreach ($filelist as $filename){
 			$this->chown($file . '/' . $filename, $owner, $recursive);
 		}
 		return true;
 	}
 	function owner($file) {
 		$owneruid = @fileowner($file);
-		if( ! $owneruid )
+		if ( ! $owneruid )
 			return false;
-		if( ! function_exists('posix_getpwuid') )
+		if ( ! function_exists('posix_getpwuid') )
 			return $owneruid;
 		$ownerarray = posix_getpwuid($owneruid);
 		return $ownerarray['name'];
 	}
 	function getchmod($file) {
-		return @fileperms($file);
+		return substr(decoct(@fileperms($file)),3);
 	}
 	function group($file) {
 		$gid = @filegroup($file);
-		if( ! $gid )
+		if ( ! $gid )
 			return false;
-		if( ! function_exists('posix_getgrgid') )
+		if ( ! function_exists('posix_getgrgid') )
 			return $gid;
 		$grouparray = posix_getgrgid($gid);
 		return $grouparray['name'];
 	}
 
 	function copy($source, $destination, $overwrite = false) {
-		if( ! $overwrite && $this->exists($destination) )
+		if ( ! $overwrite && $this->exists($destination) )
 			return false;
 		return copy($source, $destination);
 	}
 
 	function move($source, $destination, $overwrite = false) {
 		//Possible to use rename()?
-		if( $this->copy($source, $destination, $overwrite) && $this->exists($destination) ){
+		if ( $this->copy($source, $destination, $overwrite) && $this->exists($destination) ){
 			$this->delete($source);
 			return true;
 		} else {
@@ -133,11 +133,13 @@
 	}
 
 	function delete($file, $recursive = false) {
+		if ( empty($file) ) //Some filesystems report this as /, which can cause non-expected recursive deletion of all files in the filesystem.
+			return false;
 		$file = str_replace('\\', '/', $file); //for win32, occasional problems deleteing files otherwise
 
-		if( $this->is_file($file) )
+		if ( $this->is_file($file) )
 			return @unlink($file);
-		if( ! $recursive && $this->is_dir($file) )
+		if ( ! $recursive && $this->is_dir($file) )
 			return @rmdir($file);
 
 		//At this point its a folder, and we're in recursive mode
@@ -145,13 +147,13 @@
 		$filelist = $this->dirlist($file, true);
 
 		$retval = true;
-		if( is_array($filelist) ) //false if no files, So check first.
-			foreach($filelist as $filename => $fileinfo)
-				if( ! $this->delete($file . $filename, $recursive) )
+		if ( is_array($filelist) ) //false if no files, So check first.
+			foreach ($filelist as $filename => $fileinfo)
+				if ( ! $this->delete($file . $filename, $recursive) )
 					$retval = false;
 
-		if( ! @rmdir($file) )
-			return false;
+		if ( file_exists($file) && ! @rmdir($file) )
+			$retval = false;
 		return $retval;
 	}
 
@@ -187,33 +189,33 @@
 	}
 
 	function touch($file, $time = 0, $atime = 0){
-		if($time == 0)
+		if ($time == 0)
 			$time = time();
-		if($atime == 0)
+		if ($atime == 0)
 			$atime = time();
 		return @touch($file, $time, $atime);
 	}
 
 	function mkdir($path, $chmod = false, $chown = false, $chgrp = false){
-		if( ! $chmod)
+		if ( ! $chmod)
 			$chmod = $this->permission;
 
-		if( ! @mkdir($path, $chmod) )
+		if ( ! @mkdir($path, $chmod) )
 			return false;
-		if( $chown )
+		if ( $chown )
 			$this->chown($path, $chown);
-		if( $chgrp )
+		if ( $chgrp )
 			$this->chgrp($path, $chgrp);
 		return true;
 	}
 
 	function rmdir($path, $recursive = false) {
 		//Currently unused and untested, Use delete() instead.
-		if( ! $recursive )
+		if ( ! $recursive )
 			return @rmdir($path);
 		//recursive:
 		$filelist = $this->dirlist($path);
-		foreach($filelist as $filename => $det) {
+		foreach ($filelist as $filename => $det) {
 			if ( '/' == substr($filename, -1, 1) )
 				$this->rmdir($path . '/' . $filename, $recursive);
 			@rmdir($filename);
@@ -222,13 +224,13 @@
 	}
 
 	function dirlist($path, $incdot = false, $recursive = false) {
-		if( $this->is_file($path) ) {
+		if ( $this->is_file($path) ) {
 			$limitFile = basename($path);
 			$path = dirname($path);
 		} else {
 			$limitFile = false;
 		}
-		if( ! $this->is_dir($path) )
+		if ( ! $this->is_dir($path) )
 			return false;
 
 		$ret = array();
@@ -239,11 +241,11 @@
 			$struc = array();
 			$struc['name'] = $entry;
 
-			if( '.' == $struc['name'] || '..' == $struc['name'] )
+			if ( '.' == $struc['name'] || '..' == $struc['name'] )
 				continue; //Do not care about these folders.
-			if( '.' == $struc['name'][0] && !$incdot)
+			if ( '.' == $struc['name'][0] && !$incdot)
 				continue;
-			if( $limitFile && $struc['name'] != $limitFile)
+			if ( $limitFile && $struc['name'] != $limitFile)
 				continue;
 
 			$struc['perms'] 	= $this->gethchmod($path.'/'.$entry);
@@ -258,7 +260,7 @@
 			$struc['type']		= $this->is_dir($path.'/'.$entry) ? 'd' : 'f';
 
 			if ( 'd' == $struc['type'] ) {
-				if( $recursive )
+				if ( $recursive )
 					$struc['files'] = $this->dirlist($path . '/' . $struc['name'], $incdot, $recursive);
 				else
 					$struc['files'] = array();
Index: wp-admin/includes/class-wp-filesystem-ftpext.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-ftpext.php	(revision 10899)
+++ wp-admin/includes/class-wp-filesystem-ftpext.php	(working copy)
@@ -169,7 +169,7 @@
 	}
 	function getchmod($file) {
 		$dir = $this->dirlist($file);
-		return $dir[$file]['permsn'];
+		return $this->getnumchmodfromh( $dir[basename($file)]['perms'] );
 	}
 	function group($file) {
 		$dir = $this->dirlist($file);
@@ -187,7 +187,9 @@
 		return ftp_rename($this->link, $source, $destination);
 	}
 
-	function delete($file,$recursive=false) {
+	function delete($file ,$recursive = false ) {
+		if ( empty($file) )
+			return false;
 		if ( $this->is_file($file) )
 			return @ftp_delete($this->link, $file);
 		if ( !$recursive )
@@ -321,11 +323,12 @@
 	}
 
 	function dirlist($path = '.', $incdot = false, $recursive = false) {
-		if( $this->is_file($path) ) {
-			$limitFile = basename($path);
-			$path = dirname($path) . '/';
+
+		if ( substr($path, -1) !== '/') {
+			$limit = basename($path);
+			$path = trailingslashit(dirname($path));
 		} else {
-			$limitFile = false;
+			$limit = false;
 		}
 
 		$list = @ftp_rawlist($this->link, '-a ' . $path, false);
@@ -339,9 +342,12 @@
 			if ( empty($entry) )
 				continue;
 
-			if ( '.' == $entry["name"] || '..' == $entry["name"] )
+			if ( '.' == $entry['name'] || '..' == $entry['name'] )
 				continue;
 
+			if ( $limit && $entry['name'] != $limit )
+				continue;
+
 			$dirlist[ $entry['name'] ] = $entry;
 		}
 
Index: wp-admin/includes/class-wp-filesystem-ftpsockets.php
===================================================================
--- wp-admin/includes/class-wp-filesystem-ftpsockets.php	(revision 10899)
+++ wp-admin/includes/class-wp-filesystem-ftpsockets.php	(working copy)
@@ -186,7 +186,7 @@
 
 	function getchmod($file) {
 		$dir = $this->dirlist($file);
-		return $dir[$file]['permsn'];
+		return $this->getnumchmodfromh( $dir[basename($file)]['perms'] );
 	}
 
 	function group($file) {
@@ -281,21 +281,25 @@
 	}
 
 	function dirlist($path = '.', $incdot = false, $recursive = false ) {
-		if( $this->is_file($path) ) {
-			$limitFile = basename($path);
-			$path = dirname($path) . '/';
+
+		if ( substr($path, -1) !== '/') {
+			$limit = basename($path);
+			$path = trailingslashit(dirname($path));
 		} else {
-			$limitFile = false;
+			$limit = false;
 		}
 
 		$list = $this->ftp->dirlist($path);
 		if( ! $list )
 			return false;
+
 		if( empty($list) )
 			return array();
 
 		$ret = array();
 		foreach ( $list as $struc ) {
+			if ( $limit && $struc['name'] != $limit )
+				continue;
 
 			if ( 'd' == $struc['type'] ) {
 				$struc['files'] = array();
