diff -ru --exclude='fckconfig*' FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/connectors/php/commands.php FCKeditor_2.4.1-patched/editor/filemanager/browser/default/connectors/php/commands.php
--- FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/connectors/php/commands.php	2007-03-01 22:55:20.000000000 +0000
+++ FCKeditor_2.4.1-patched/editor/filemanager/browser/default/connectors/php/commands.php	2007-03-27 12:56:52.000000000 +0100
@@ -177,33 +177,70 @@
 
 		$arAllowed	= $Config['AllowedExtensions'][$resourceType] ;
 		$arDenied	= $Config['DeniedExtensions'][$resourceType] ;
+		$arRegexp	= (isSet ($Config['Regexp']) && array_key_exists ($resourceType, $Config['Regexp']) ? $Config['Regexp'][$resourceType] : '');
 
-		if ( ( count($arAllowed) == 0 || in_array( $sExtension, $arAllowed ) ) && ( count($arDenied) == 0 || !in_array( $sExtension, $arDenied ) ) )
+		if ( ( count($arAllowed) == 0 || in_array( $sExtension, $arAllowed ) ) && ( count($arDenied) == 0 || !in_array( $sExtension, $arDenied ) ) && ( $arRegexp === '' || ereg( $arRegexp, RemoveExtension( $sOriginalFileName ) ) ) )
 		{
-			$iCounter = 0 ;
-
-			while ( true )
-			{
-				$sFilePath = $sServerDir . $sFileName ;
-
+			// Assign the new file's name
+			$sFilePath = $sServerDir . $sFileName ;
+			$doUpload = true;
+			
+			// If the file already exists, select what behaviour should be adopted
+			if ( is_file( $sFilePath ) ) {
+				$sFilenameClashBehaviour = (isSet ($Config['filenameClashBehaviour']) ? $Config['filenameClashBehaviour'] : 'newname');
+				switch ($sFilenameClashBehaviour) {
+					
+					// overwrites the version on the server with the same name
+					case 'overwrite':
+						$sErrorNumber = '204' ;
+						// Do nothing - move_uploaded_file will just overwrite naturally
+						break;
+						
+					// generate an error so that the file uploading fails
+					case false:
+					case 'false':	// String version in case someone quotes the boolean text equivalent
+						$sErrorNumber = '205' ;
+						$doUpload = false;
+						break;
+					
+					// give the uploaded file a new name (this was the (unconfigurable) behaviour in FCKeditor2.2) - named as: originalName(number).extension
+					case 'newname':
+						$iCounter = 0 ;
+						while ( true )
+						{
+							if ( is_file( $sFilePath ) )
+							{
+								$iCounter++ ;
+								$sFileName = RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension ;
+								$sErrorNumber = '201' ;
+								$sFilePath = $sServerDir . $sFileName ;
+							}
+							else
+							{
+								break ;
+							}
+						}
+						break;
+						
+					// (default behaviour) back up the version on the server to the same name + timestamp appended to the filename (after the extension)
+					case 'renameold':
+					default:
+						$timestamp = '.' . date ('Ymd-His');
+						copy ($sFilePath, $sFilePath . $timestamp);
+						$sFileName = $sFileName . $timestamp;
+						$sErrorNumber = '206' ;
+						break;
+				}	// End of switch statement
+			}
+			
+			// Now its name has been assigned, move the uploaded file into position
+			if ($doUpload) {
+				move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ;
 				if ( is_file( $sFilePath ) )
 				{
-					$iCounter++ ;
-					$sFileName = RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension ;
-					$sErrorNumber = '201' ;
-				}
-				else
-				{
-					move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ;
-
-					if ( is_file( $sFilePath ) )
-					{
-						$oldumask = umask(0) ;
-						chmod( $sFilePath, 0777 ) ;
-						umask( $oldumask ) ;
-					}
-
-					break ;
+					$oldumask = umask(0) ;
+					chmod( $sFilePath, 0777 ) ;
+					umask( $oldumask ) ;
 				}
 			}
 		}
diff -ru --exclude='fckconfig*' FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/connectors/php/config.php FCKeditor_2.4.1-patched/editor/filemanager/browser/default/connectors/php/config.php
--- FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/connectors/php/config.php	2007-03-06 11:21:08.000000000 +0000
+++ FCKeditor_2.4.1-patched/editor/filemanager/browser/default/connectors/php/config.php	2007-03-27 13:22:09.000000000 +0100
@@ -24,33 +24,57 @@
 
 global $Config ;
 
-// SECURITY: You must explicitelly enable this "connector". (Set it to "true").
+// SECURITY: You must explicitly enable this "connector". (Set it to "true").
 $Config['Enabled'] = false ;
 
 
 // Path to user files relative to the document root.
-$Config['UserFilesPath'] = '/userfiles/' ;
+$Config['UserFilesPath'] = '/userfiles/' ;	// Set to / if you want filebrowsing across the whole site directory
 
 // Fill the following value it you prefer to specify the absolute path for the
-// user files directory. Usefull if you are using a virtual directory, symbolic
+// user files directory. Useful if you are using a virtual directory, symbolic
 // link or alias. Examples: 'C:\\MySite\\userfiles\\' or '/root/mysite/userfiles/'.
 // Attention: The above 'UserFilesPath' must point to the same directory.
-$Config['UserFilesAbsolutePath'] = '' ;
+$Config['UserFilesAbsolutePath'] = '' ;	// Set to $_SERVER['DOCUMENT_ROOT'] if you want filebrowsing across the whole site
 
 // Due to security issues with Apache modules, it is reccomended to leave the
 // following setting enabled.
 $Config['ForceSingleExtension'] = true ;
 
+// What to do if a file being uploaded has the same name as an existing file on the server
+// 	'renameold' - (default behaviour) backs up the version on the server to the same name + timestamp appended to the filename (after the extension)
+//	'overwrite' - overwrites the version on the server with the same name
+// 	'newname' - gives the uploaded file a new name (this was the (unconfigurable) behaviour in FCKeditor2.2)
+// 	false - generates an error so that the file uploading fails
+$Config['filenameClashBehaviour'] = 'renameold';
+
+// In the following groupings:
+//		'Subdirectory' is the subdirectory under the main 'UserFilesPath'
+//			e.g. 'File/'
+//			or leave it blank as '' to use the main UserFilesPath directory (i.e. the user can add files across the whole site)
+//		'Regexp' ereg-style regexp which the name must validate to
+//			This regexp applies to the part BEFORE the dot + file extension
+//			e.g. '^([-_a-zA-Z0-9]{1,25})$'   (which would be sensible for best practice)
+//			or leave it blank as '' for no checking
+
+$Config['Subdirectory']['File']	= 'file/' ;
 $Config['AllowedExtensions']['File']	= array() ;
 $Config['DeniedExtensions']['File']		= array('html','htm','php','php2','php3','php4','php5','phtml','pwml','inc','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','com','dll','vbs','js','reg','cgi','htaccess','asis') ;
+$Config['Regexp']['File']	= '' ;
 
+$Config['Subdirectory']['Image']	= 'image/' ;
 $Config['AllowedExtensions']['Image']	= array('jpg','gif','jpeg','png') ;
 $Config['DeniedExtensions']['Image']	= array() ;
+$Config['Regexp']['Image']	= '' ;
 
+$Config['Subdirectory']['Flash']	= 'flash/' ;
 $Config['AllowedExtensions']['Flash']	= array('swf','fla') ;
 $Config['DeniedExtensions']['Flash']	= array() ;
+$Config['Regexp']['Flash']	= '' ;
 
+$Config['Subdirectory']['Media']	= 'media/' ;
 $Config['AllowedExtensions']['Media']	= array('swf','fla','jpg','gif','jpeg','png','avi','mpg','mpeg') ;
 $Config['DeniedExtensions']['Media']	= array() ;
+$Config['Regexp']['Media']	= '' ;
 
 ?>
\ No newline at end of file
diff -ru --exclude='fckconfig*' FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/connectors/php/connector.php FCKeditor_2.4.1-patched/editor/filemanager/browser/default/connectors/php/connector.php
--- FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/connectors/php/connector.php	2007-03-01 22:55:20.000000000 +0000
+++ FCKeditor_2.4.1-patched/editor/filemanager/browser/default/connectors/php/connector.php	2007-03-27 13:04:42.000000000 +0100
@@ -36,6 +36,11 @@
 // Get the "UserFiles" path.
 $GLOBALS["UserFilesPath"] = '' ;
 
+// Global the subdirectories for the media types
+if (isSet ($Config['Subdirectory'])) {
+	$GLOBALS['Subdirectory'] = $Config['Subdirectory'] ;
+}
+
 if ( isset( $Config['UserFilesPath'] ) )
 	$GLOBALS["UserFilesPath"] = $Config['UserFilesPath'] ;
 else if ( isset( $_GET['ServerPath'] ) )
diff -ru --exclude='fckconfig*' FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/connectors/php/io.php FCKeditor_2.4.1-patched/editor/filemanager/browser/default/connectors/php/io.php
--- FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/connectors/php/io.php	2007-03-01 22:55:20.000000000 +0000
+++ FCKeditor_2.4.1-patched/editor/filemanager/browser/default/connectors/php/io.php	2007-03-27 13:13:19.000000000 +0100
@@ -24,10 +24,7 @@
 
 function GetUrlFromPath( $resourceType, $folderPath )
 {
-	if ( $resourceType == '' )
-		return RemoveFromEnd( $GLOBALS["UserFilesPath"], '/' ) . $folderPath ;
-	else
-		return $GLOBALS["UserFilesPath"] . strtolower( $resourceType ) . $folderPath ;
+	return $GLOBALS["UserFilesPath"] . GetResourceTypeSubdirectory ( $resourceType ) . RemoveFromStart ( $folderPath , '/' );
 }
 
 function RemoveExtension( $fileName )
@@ -38,7 +35,7 @@
 function ServerMapFolder( $resourceType, $folderPath )
 {
 	// Get the resource type directory.
-	$sResourceTypePath = $GLOBALS["UserFilesDirectory"] . strtolower( $resourceType ) . '/' ;
+	$sResourceTypePath = $GLOBALS["UserFilesDirectory"] . GetResourceTypeSubdirectory ( $resourceType );
 
 	// Ensure that the directory exists.
 	CreateServerFolder( $sResourceTypePath ) ;
@@ -47,6 +44,27 @@
 	return $sResourceTypePath . RemoveFromStart( $folderPath, '/' ) ;
 }
 
+
+// Function to determine the directory where the files for this resource type are located
+function GetResourceTypeSubdirectory ( $resourceType )
+{
+	// Return the empty string if no resource type specified, i.e. don't go down into any subdirectory
+	if ($resourceType == '') {return '';}
+	
+	// Use the configured value if it exists; NB array_key_exists is used rather than isSet to allow empty values
+	if (isSet ($GLOBALS['Subdirectory']) && array_key_exists ($resourceType, $GLOBALS['Subdirectory'])) {
+		
+		// If the value is empty, don't add a slash to the empty string, and return that
+		if ($GLOBALS['Subdirectory'][$resourceType] == '') {return '';}
+		
+		// Otherwise ensure the subdirectory is slash-terminated, and return that
+		return RemoveFromEnd( $GLOBALS['Subdirectory'][$resourceType], '/' ) . '/';
+	}
+	
+	// Otherwise default to the resource type name itself as the directory name
+	return strtolower ( $resourceType ) . '/';
+}
+
 function GetParentFolder( $folderPath )
 {
 	$sPattern = "-[/\\\\][^/\\\\]+[/\\\\]?$-" ;
@@ -55,6 +73,12 @@
 
 function CreateServerFolder( $folderPath )
 {
+	// Ensure the folder path has no double-slashes, or mkdir may fail on certain platforms
+	while (strpos ($folderPath, '//') !== false)
+	{
+		$folderPath = str_replace( '//', '/', $folderPath ) ;
+	}
+	
 	$sParent = GetParentFolder( $folderPath ) ;
 
 	// Check if the parent exists, or create it.
diff -ru --exclude='fckconfig*' FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/frmupload.html FCKeditor_2.4.1-patched/editor/filemanager/browser/default/frmupload.html
--- FCKeditor_2.4.1-virgin/editor/filemanager/browser/default/frmupload.html	2007-03-01 22:55:20.000000000 +0000
+++ FCKeditor_2.4.1-patched/editor/filemanager/browser/default/frmupload.html	2007-03-27 13:16:46.000000000 +0100
@@ -81,6 +81,17 @@
 		case 202 :
 			alert( 'Invalid file' ) ;
 			break ;
+		case 204 :
+			window.parent.frames['frmResourcesList'].Refresh() ;
+			alert( 'Your file has been successfully uploaded, and replaced the existing file with the same name.' ) ;
+			break ;
+		case 205 :
+			alert( 'A file of that name already exists, so the upload failed.' ) ;
+			break ;
+		case 206 :
+			window.parent.frames['frmResourcesList'].Refresh() ;
+			alert( 'Your file has been successfully uploaded. There was already a file of that name, so that previous file has been backed up by being renamed to "' + data + '".' ) ;
+			break ;
 		default :
 			alert( 'Error on file upload. Error number: ' + errorNumber ) ;
 			break ;
