Index: t3lib/config_default.php
===================================================================
--- t3lib/config_default.php	(Revision 5205)
+++ t3lib/config_default.php	(Arbeitskopie)
@@ -237,6 +237,7 @@
 		'AJAX' => array(				// array of key-value pairs for a unified use of AJAX calls in the TYPO3 backend. Keys are the unique ajaxIDs where the value will be resolved to call a method in an object. See ajax.php and the classes/class.typo3ajax.php for more information.
 			'SC_alt_db_navframe::expandCollapse'                => 'typo3/alt_db_navframe.php:SC_alt_db_navframe->ajaxExpandCollapse',
 			'SC_alt_file_navframe::expandCollapse'              => 'typo3/alt_file_navframe.php:SC_alt_file_navframe->ajaxExpandCollapse',
+			'TYPO3_tcefile::process'                            => 'typo3/classes/class.typo3_tcefile.php:TYPO3_tcefile->processAjaxRequest',
 			't3lib_TCEforms_inline::createNewRecord'		    => 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
 			't3lib_TCEforms_inline::synchronizeLocalizeRecords'	=> 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
 			't3lib_TCEforms_inline::setExpandedCollapsedState'	=> 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
Index: t3lib/class.t3lib_extfilefunc.php
===================================================================
--- t3lib/class.t3lib_extfilefunc.php	(Revision 5205)
+++ t3lib/class.t3lib_extfilefunc.php	(Arbeitskopie)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -210,19 +210,24 @@
 	/**
 	 * Processing the command array in $this->fileCmdMap
 	 *
-	 * @return	void
+	 * @return	mixed	false, if the file functions were not initialized 
+	 *					otherwise returns an array of all the results that are returned
+	 *					from each command, separated in each action.
 	 */
-	function processData()	{
-		if (!$this->isInit) return FALSE;
+	function processData() {
+		$result = array();
+		if (!$this->isInit) {
+			return false;
+		}
 
-		if (is_array($this->fileCmdMap))	{
+		if (is_array($this->fileCmdMap)) {
 
 				// Check if there were uploads expected, but no one made
-			if ($this->fileCmdMap['upload'])	{
+			if ($this->fileCmdMap['upload']) {
 				$uploads = $this->fileCmdMap['upload'];
-				foreach ($uploads as $arr)	{
-					if (!$_FILES['upload_'.$arr['data']]['name'])	{
-						unset($this->fileCmdMap['upload'][$arr['data']]);
+				foreach ($uploads as $upload) {
+					if (!$_FILES['upload_' . $upload['data']]['name']) {
+						unset($this->fileCmdMap['upload'][$upload['data']]);
 					}
 				}
 				if (count($this->fileCmdMap['upload']) == 0) {
@@ -231,49 +236,51 @@
 			}
 
 				// Traverse each set of actions
-			foreach($this->fileCmdMap as $action => $actionData)	{
+			foreach ($this->fileCmdMap as $action => $actionData) {
 
 					// Traverse all action data. More than one file might be affected at the same time.
-				if (is_array($actionData))	{
-					foreach($actionData as $cmdArr)	{
+				if (is_array($actionData)) {
+				    $result[$action] = array();
+					foreach ($actionData as $cmdArr) {
 
 							// Clear file stats
 						clearstatcache();
 
 							// Branch out based on command:
-						switch ($action)	{
+						switch ($action) {
 							case 'delete':
-								$this->func_delete($cmdArr);
+								$result[$action][] = $this->func_delete($cmdArr);
 							break;
 							case 'copy':
-								$this->func_copy($cmdArr);
+								$result[$action][] = $this->func_copy($cmdArr);
 							break;
 							case 'move':
-								$this->func_move($cmdArr);
+								$result[$action][] = $this->func_move($cmdArr);
 							break;
 							case 'rename':
-								$this->func_rename($cmdArr);
+								$result[$action][] = $this->func_rename($cmdArr);
 							break;
 							case 'newfolder':
-								$this->func_newfolder($cmdArr);
+								$result[$action][] = $this->func_newfolder($cmdArr);
 							break;
 							case 'newfile':
-								$this->func_newfile($cmdArr);
+								$result[$action][] = $this->func_newfile($cmdArr);
 							break;
 							case 'editfile':
-								$this->func_edit($cmdArr);
+								$result[$action][] = $this->func_edit($cmdArr);
 							break;
 							case 'upload':
-								$this->func_upload($cmdArr);
+								$result[$action][] = $this->func_upload($cmdArr);
 							break;
 							case 'unzip':
-								$this->func_unzip($cmdArr);
+								$result[$action][] = $this->func_unzip($cmdArr);
 							break;
 						}
 					}
 				}
 			}
 		}
+		return $result;
 	}
 
 	/**
@@ -282,58 +289,74 @@
 	 * @param	string		Redirect URL (for creating link in message)
 	 * @return	void		(Will exit on error)
 	 */
-	function printLogErrorMessages($redirect='')	{
+	function printLogErrorMessages($redirect = '') {
+			// fetch the error messages from the DB
+		$errorMessages = $this->getErrorMessages();
 
-		$res_log = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
-					'*',
-					'sys_log',
-					'type=2 AND userid='.intval($GLOBALS['BE_USER']->user['uid']).' AND tstamp='.intval($GLOBALS['EXEC_TIME']).'	AND error!=0'
-				);
-		$errorJS = array();
-		while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_log)) {
-			$log_data = unserialize($row['log_data']);
-			$errorJS[] = $row[error].': '.sprintf($row['details'], $log_data[0],$log_data[1],$log_data[2],$log_data[3],$log_data[4]);
-		}
+			// only print error messages if there is an error
+		if (count($errorMessages)) {
+			$errorDoc = t3lib_div::makeInstance('template');
+			$errorDoc->backPath = '';
 
-		if (count($errorJS))	{
-			$error_doc = t3lib_div::makeInstance('template');
-			$error_doc->backPath = '';
+			$content = $errorDoc->startPage('tce_db.php Error output');
 
-			$content.= $error_doc->startPage('tce_db.php Error output');
-
 			$lines[] = '
 					<tr class="bgColor5">
 						<td colspan="2" align="center"><strong>Errors:</strong></td>
 					</tr>';
 
-			foreach($errorJS as $line)	{
+			foreach ($errorMessages as $line) {
 				$lines[] = '
 					<tr class="bgColor4">
-						<td valign="top"><img'.t3lib_iconWorks::skinImg('','gfx/icon_fatalerror.gif','width="18" height="16"').' alt="" /></td>
-						<td>'.htmlspecialchars($line).'</td>
+						<td valign="top"><img' . t3lib_iconWorks::skinImg('', 'gfx/icon_fatalerror.gif', 'width="18" height="16"') . ' alt="" /></td>
+						<td>' . htmlspecialchars($line) . '</td>
 					</tr>';
 			}
 
 			$lines[] = '
 					<tr>
 						<td colspan="2" align="center"><br />'.
-						'<form action=""><input type="submit" value="Continue" onclick="'.htmlspecialchars('window.location.href=\''.$redirect.'\';return false;').'" /></form>'.
+						'<form action=""><input type="submit" value="Continue" onclick="'.htmlspecialchars('window.location.href=\'' . $redirect . '\';return false;').'" /></form>'.
 						'</td>
 					</tr>';
 
-			$content.= '
+			$content .= '
 				<br /><br />
 				<table border="0" cellpadding="1" cellspacing="1" width="300" align="center">
-					'.implode('',$lines).'
+					' . implode('', $lines) . '
 				</table>';
 
-			$content.= $error_doc->endPage();
-			echo $content;
-			exit;
+			$content .= $errorDoc->endPage();
+			die($content);
 		}
 	}
 
+
 	/**
+	 * Returns log error messages from the previous file operations of this script instance
+	 *
+	 * @return	array	all errorMessages as a numerical array
+	 */
+	function getErrorMessages() {
+		$errorMessages = array();
+		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+				'*',
+				'sys_log',
+				'type = 2 AND userid = ' . intval($GLOBALS['BE_USER']->user['uid'])
+				. ' AND tstamp=' . intval($GLOBALS['EXEC_TIME'])
+				. ' AND error != 0'
+		);
+		while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+			$logData = unserialize($row['log_data']);
+			$errorMessages[] = $row['error'] . ': ' . sprintf($row['details'], $logData[0], $logData[1], $logData[2], $logData[3], $logData[4]);
+		}
+		$GLOBALS['TYPO3_DB']->sql_free_result($res);
+		return $errorMessages;
+	}
+
+
+
+	/**
 	 * Goes back in the path and checks in each directory if a folder named $this->recyclerFN (usually '_recycler_') is present.
 	 * If a folder in the tree happens to be a _recycler_-folder (which means that we're deleting something inside a _recycler_-folder) this is ignored
 	 *
@@ -788,7 +811,7 @@
 	/**
 	 * Upload of files (action=1)
 	 *
-	 * @param	array		$cmds['data'] is the ID-number (points to the global var that holds the filename-ref  ($_FILES['upload_'.$id]['name']). $cmds['target'] is the target directory
+	 * @param	array		$cmds['data'] is the ID-number (points to the global var that holds the filename-ref  ($_FILES['upload_'.$id]['name']). $cmds['target'] is the target directory, $cmds['charset'] is the the character set of the file name (utf-8 is needed for JS-interaction)
 	 * @return	string		Returns the new filename upon success
 	 */
 	function func_upload($cmds)	{
@@ -797,7 +820,7 @@
 		if ($_FILES['upload_'.$id]['name'])	{
 			$theFile = $_FILES['upload_'.$id]['tmp_name'];				// filename of the uploaded file
 			$theFileSize = $_FILES['upload_'.$id]['size'];				// filesize of the uploaded file
-			$theName = $this->cleanFileName(stripslashes($_FILES['upload_'.$id]['name']));	// The original filename
+			$theName = $this->cleanFileName(stripslashes($_FILES['upload_'.$id]['name']), (isset($cmds['charset']) ? $cmds['charset'] : ''));	// The original filename
 			if (is_uploaded_file($theFile) && $theName)	{	// Check the file
 				if ($this->actionPerms['uploadFile'])	{
 					if ($theFileSize<($this->maxUploadFileSize*1024))	{
Index: typo3/classes/class.typo3_tcefile.php
===================================================================
--- typo3/classes/class.typo3_tcefile.php	(Revision 0)
+++ typo3/classes/class.typo3_tcefile.php	(Revision 0)
@@ -0,0 +1,188 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 2009 Benjamin Mack (benni.typo3.org)
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * Gateway for TCE (TYPO3 Core Engine) file-handling through POST forms.
+ * This script serves as the fileadministration part of the TYPO3 Core Engine.
+ * Basically it includes two libraries which are used to manipulate files on the server.
+ * Before TYPO3 4.3, it was located in typo3/tce_file.php and redirected back to a
+ * $redirectURL. Since 4.3 this class is also used for accessing via AJAX
+ * 
+ *
+ * For syntax and API information, see the document 'TYPO3 Core APIs'
+ *
+ * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
+ * Revised for TYPO3 4.3 Mar/2009 by Benjamin Mack
+ *
+ * @author	Kasper Skaarhoj <kasperYYYY@typo3.com>
+ */
+
+require_once(PATH_typo3 . 'template.php');
+require_once(PATH_t3lib . 'class.t3lib_basicfilefunc.php');
+require_once(PATH_t3lib . 'class.t3lib_extfilefunc.php');
+require_once(PATH_t3lib . 'class.t3lib_clipboard.php');
+
+/**
+ * Script Class, handling the calling of methods in the file admin classes.
+ *
+ * @author	Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @package TYPO3
+ * @subpackage core
+ */
+class TYPO3_tcefile {
+
+		// Internal, static: GPvar:
+		// Array of file-operations.
+	protected $file;
+		// Clipboard operations array
+	protected $CB;
+		// If existing files should be overridden.
+	protected $overwriteExistingFiles;
+		// VeriCode - a hash of server specific value and other things which
+		// identifies if a submission is OK. (see $BE_USER->veriCode())
+	protected $vC;
+	    // the page where the user should be redirected after everything is done
+	protected $redirect;
+
+		// Internal, dynamic:
+		// File processor object
+	protected $fileProcessor;
+	    // the result array from the file processor
+	protected $fileData;
+
+
+
+	/**
+	 * Registering incoming data
+	 *
+	 * @return	void
+	 */
+	public function init() {
+			// set the GPvars from outside
+		$this->file = t3lib_div::_GP('file');
+		$this->CB = t3lib_div::_GP('CB');
+		$this->overwriteExistingFiles = t3lib_div::_GP('overwriteExistingFiles');
+		$this->vC = t3lib_div::_GP('vC');
+		$this->redirect = t3lib_div::_GP('redirect');
+
+		$this->initClipboard();
+	}
+
+	/**
+	 * Initialize the Clipboard. This will fetch the data about files to paste/delete if such an action has been sent.
+	 *
+	 * @return	void
+	 */
+	public function initClipboard() {
+		if (is_array($this->CB)) {
+			$clipObj = t3lib_div::makeInstance('t3lib_clipboard');
+			$clipObj->initializeClipboard();
+			if ($this->CB['paste']) {
+				$clipObj->setCurrentPad($this->CB['pad']);
+				$this->file = $clipObj->makePasteCmdArray_file($this->CB['paste'], $this->file);
+			}
+			if ($this->CB['delete']) {
+				$clipObj->setCurrentPad($this->CB['pad']);
+				$this->file = $clipObj->makeDeleteCmdArray_file($this->file);
+			}
+		}
+	}
+
+	/**
+	 * Performing the file admin action:
+	 * Initializes the objects, setting permissions, sending data to object.
+	 *
+	 * @return	void
+	 */
+	public function main() {
+			// Initializing:
+		$this->fileProcessor = t3lib_div::makeInstance('t3lib_extFileFunctions');
+		$this->fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
+		$this->fileProcessor->init_actionPerms($GLOBALS['BE_USER']->getFileoperationPermissions());
+		$this->fileProcessor->dontCheckForUnique = ($this->overwriteExistingFiles ? 1 : 0);
+
+			// Checking referer / executing:
+		$refInfo = parse_url(t3lib_div::getIndpEnv('HTTP_REFERER'));
+		$httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
+		if ($httpHost != $refInfo['host']
+			&& $this->vC != $GLOBALS['BE_USER']->veriCode()
+			&& !$GLOBALS['TYPO3_CONF_VARS']['SYS']['doNotCheckReferer']
+			&& $GLOBALS['CLIENT']['BROWSER'] != 'flash') {
+			$this->fileProcessor->writeLog(0, 2, 1, 'Referer host "%s" and server host "%s" did not match!', array($refInfo['host'], $httpHost));
+		} else {
+			$this->fileProcessor->start($this->file);
+			$this->fileData = $this->fileProcessor->processData();
+		}
+	}
+
+	/**
+	 * Redirecting the user after the processing has been done.
+	 * Might also display error messages directly, if any.
+	 *
+	 * @return	void
+	 */
+	public function finish() {
+			// Prints errors, if there are any
+		$this->fileProcessor->printLogErrorMessages($this->redirect);
+		t3lib_BEfunc::getSetUpdateSignal('updateFolderTree');
+		if ($this->redirect) {
+			header('Location: ' . t3lib_div::locationHeaderUrl($this->redirect));
+		}
+	}
+
+	/**
+	 * Handles the actual process from within the ajaxExec function
+	 * therefore, it does exactly the same as the real typo3/tce_file.php
+	 * but without calling the "finish" method, thus makes it simpler to deal with the
+	 * actual return value
+	 * 
+	 *
+	 * @param string $params 	always empty.
+	 * @param string $ajaxObj	The Ajax object used to return content and set content types
+	 * @return void
+	 */
+	public function processAjaxRequest(array $params, TYPO3AJAX $ajaxObj) {
+		$this->init();
+		$this->main();
+		$errors = $this->fileProcessor->getErrorMessages();
+		if (count($errors)) {
+			$ajaxObj->setError(implode(',', $errors));
+		} else {
+			$ajaxObj->addContent('result', $this->fileData);
+			if ($this->redirect) {
+				$ajaxObj->addContent('redirect', $this->redirect);
+			}
+			$ajaxObj->setContentFormat('json');
+		}
+	}
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/classes/class.typo3_tcefile.php']) {
+	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/classes/class.typo3_tcefile.php']);
+}
+
+?>
\ No newline at end of file
Index: typo3/tce_file.php
===================================================================
--- typo3/tce_file.php	(Revision 5205)
+++ typo3/tce_file.php	(Arbeitskopie)
@@ -52,134 +52,12 @@
  *
  */
 
-require('init.php');
-require('template.php');
-require_once(PATH_t3lib . 'class.t3lib_basicfilefunc.php');
-require_once(PATH_t3lib . 'class.t3lib_extfilefunc.php');
+require_once('init.php');
+require_once('classes/class.typo3_tcefile.php');
 
-
-
-/**
- * Script Class, handling the calling of methods in the file admin classes.
- *
- * @author	Kasper Skaarhoj <kasperYYYY@typo3.com>
- * @package TYPO3
- * @subpackage core
- */
-class SC_tce_file {
-
-		// Internal, static: GPvar:
-	var $file;						// Array of file-operations.
-	var $redirect;					// Redirect URL
-	var $CB;						// Clipboard operations array
-	var $overwriteExistingFiles;	// If existing files should be overridden.
-	var $vC;						// VeriCode - a hash of server specific value and other things which identifies if a submission is OK. (see $BE_USER->veriCode())
-
-		// Internal, dynamic:
-	var $include_once = array();	// Used to set the classes to include after the init() function is called.
-	var $fileProcessor;				// File processor object
-
-
-
-	/**
-	 * Registering Incoming data
-	 *
-	 * @return	void
-	 */
-	function init() {
-			// GPvars:
-		$this->file = t3lib_div::_GP('file');
-		$this->redirect = t3lib_div::_GP('redirect');
-		$this->CB = t3lib_div::_GP('CB');
-		$this->overwriteExistingFiles = t3lib_div::_GP('overwriteExistingFiles');
-		$this->vC = t3lib_div::_GP('vC');
-
-			// If clipboard is set, then include the clipboard class:
-		if (is_array($this->CB)) {
-			$this->include_once[] = PATH_t3lib . 'class.t3lib_clipboard.php';
-		}
-	}
-
-	/**
-	 * Initialize the Clipboard. This will fetch the data about files to paste/delete if such an action has been sent.
-	 *
-	 * @return	void
-	 */
-	function initClipboard() {
-		if (is_array($this->CB)) {
-			$clipObj = t3lib_div::makeInstance('t3lib_clipboard');
-			$clipObj->initializeClipboard();
-			if ($this->CB['paste']) {
-				$clipObj->setCurrentPad($this->CB['pad']);
-				$this->file = $clipObj->makePasteCmdArray_file($this->CB['paste'], $this->file);
-			}
-			if ($this->CB['delete']) {
-				$clipObj->setCurrentPad($this->CB['pad']);
-				$this->file = $clipObj->makeDeleteCmdArray_file($this->file);
-			}
-		}
-	}
-
-	/**
-	 * Performing the file admin action:
-	 * Initializes the objects, setting permissions, sending data to object.
-	 *
-	 * @return	void
-	 */
-	function main() {
-		global $FILEMOUNTS,$TYPO3_CONF_VARS,$BE_USER;
-
-			// Initializing:
-		$this->fileProcessor = t3lib_div::makeInstance('t3lib_extFileFunctions');
-		$this->fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
-		$this->fileProcessor->init_actionPerms($GLOBALS['BE_USER']->getFileoperationPermissions());
-		$this->fileProcessor->dontCheckForUnique = $this->overwriteExistingFiles ? 1 : 0;
-
-			// Checking referer / executing:
-		$refInfo = parse_url(t3lib_div::getIndpEnv('HTTP_REFERER'));
-		$httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
-		if ($httpHost != $refInfo['host'] && $this->vC != $GLOBALS['BE_USER']->veriCode() && !$GLOBALS['TYPO3_CONF_VARS']['SYS']['doNotCheckReferer']) {
-			$this->fileProcessor->writeLog(0, 2, 1, 'Referer host "%s" and server host "%s" did not match!', array($refInfo['host'], $httpHost));
-		} else {
-			$this->fileProcessor->start($this->file);
-			$this->fileProcessor->processData();
-		}
-	}
-
-	/**
-	 * Redirecting the user after the processing has been done.
-	 * Might also display error messages directly, if any.
-	 *
-	 * @return	void
-	 */
-	function finish() {
-			// Prints errors, if...
-		$this->fileProcessor->printLogErrorMessages($this->redirect);
-
-		t3lib_BEfunc::getSetUpdateSignal('updateFolderTree');
-		if ($this->redirect) {
-			Header('Location: '.t3lib_div::locationHeaderUrl($this->redirect));
-		}
-	}
-}
-
-
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/tce_file.php']) {
-	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/tce_file.php']);
-}
-
-
-
 // Make instance:
-$SOBE = t3lib_div::makeInstance('SC_tce_file');
+$SOBE = t3lib_div::makeInstance('TYPO3_tcefile');
 $SOBE->init();
-
-// Include files?
-foreach ($SOBE->include_once as $INC_FILE) {
-    include_once($INC_FILE);
-}
-
-$SOBE->initClipboard();
 $SOBE->main();
 $SOBE->finish();
 
