function acceptFiles($uploadedFilesArray)
{
    // --------------
    // This PHP function takes files that were just uploaded with HTTP POST,
    // verifies if the size is smaller than a certain value, and moves them
    // using move_uploaded_file() from the server's temporary directory to
    // net2ftp's temporary directory
    //
    // $uploadedFilesArray[number]["name"] and $acceptedFilesArray[number]["name"] contain the real name of the file
    // $uploadedFilesArray[number]["tmp_name"] contains the temporary name of the file in the *webserver's* temporary directory (eg C:\temp)
    // $acceptedFilesArray[number]["tmp_name"] contains the temporary name of the file in *net2ftp's* temporary directory (eg C:\web\net2ftp\temp)
    //
    // Note 1 - $acceptedFilesArray[number]["tmp_name"] may not be the same as $uploadedFilesArray[number]["tmp_name"] because
    //          $acceptedFilesArray[number]["tmp_name"] should be unique at the moment the file is transferred to the new directory.
    // Note 2 - $acceptedFilesArray[number]["tmp_name"]
    //            - starts with upload (or upl on Windows, because on that platform only the first 3 letters are kept)
    //            - has the same filename extension as the real filename
    //            - ends with .txt
    //     The filename extension is needed by the PCL TAR library, which needs to determine if the archive is tar, tgz or gz.
    //     The additional .txt is to ensure that no temporary file would be executed on the web server, which could compromise it.
    //
    // For example: script.php is uploaded to the web server's temporary directory C:\temp\f9skpqri
    //              Then it is moved to net2ftp's temporary directory C:\web\net2ftp\temp\upload9oeic.php.txt
    //              And finally it is transferred to the FTP server as script.php in functions ftp_transferfiles() and ftp_unziptransferfiles() -- see below
    // --------------
    // -------------------------------------------------------------------------
    // Global variables
    // -------------------------------------------------------------------------
    global $net2ftp_globals, $net2ftp_settings, $net2ftp_output;
    $max_filesize = $net2ftp_settings["max_filesize"];
    $skipped = 0;
    // Index of the files which are too big / contain a banned keyword
    $moved_ok = 0;
    // Index of the files that have been treated successfully
    $moved_notok = 0;
    // Index of the files that have been treated unsuccessfully
    for ($i = 1; $i <= sizeof($uploadedFilesArray); $i++) {
        // -------------------------------------------------------------------------
        // 1 -- Get the data from the filesArray (for each file, its location, name, size, ftpmode
        // -------------------------------------------------------------------------
        $file_name = $uploadedFilesArray["{$i}"]["name"];
        $file_tmp_name = $uploadedFilesArray["{$i}"]["tmp_name"];
        $file_size = $uploadedFilesArray["{$i}"]["size"];
        if ($file_name != "" && $file_tmp_name == "" || $file_size > $max_filesize) {
            // The case ($file_name != "" && $file_tmp_name == "") occurs when the file is bigger than the directives set in php.ini
            // In that case, only $uploadedFilesArray["$i"]["name"] is filled in.
            $net2ftp_output["acceptFiles"][] = __("File <b>%1\$s</b> is too big. This file will not be uploaded.", $file_name);
            $skipped = $skipped + 1;
            @unlink($file_tmp_name);
            continue;
        } elseif (checkAuthorizedName($file_name) == false) {
            $net2ftp_output["acceptFiles"][] = __("File <b>%1\$s</b> is contains a banned keyword. This file will not be uploaded.", $file_name);
            $skipped = $skipped + 1;
            @unlink($file_tmp_name);
            continue;
        }
        // -------------------------------------------------------------------------
        // 3 -- upload and copy the file; if a file with the same name already exists, it is overwritten with the new file
        // -------------------------------------------------------------------------
        $extension = get_filename_extension($file_name);
        if (substr($file_name, -6) == "tar.gz") {
            $extension = "tar.gz";
        }
        $tempfilename = tempnam2($net2ftp_globals["application_tempdir"], "upload__", "." . $extension . ".txt");
        if ($tempfilename == false) {
            @unlink($tempfilename);
            $errormessage = __("Could not generate a temporary file.");
            setErrorVars(false, $errormessage, debug_backtrace(), __FILE__, __LINE__);
            return false;
        }
        $success2 = move_uploaded_file($file_tmp_name, $tempfilename);
        if ($success2 == false) {
            $net2ftp_output["acceptFiles"][] = __("File <b>%1\$s</b> could not be moved", $file_name);
            @unlink($file_tmp_name);
            @unlink($tempfilename);
            $moved_notok = $moved_notok + 1;
            continue;
        } else {
            // When uploading files, print some output
            // When updating files, do not print anything
            registerTempfile("register", $tempfilename);
            if ($net2ftp_globals["state"] == "upload") {
                $net2ftp_output["acceptFiles"][] = __("File <b>%1\$s</b> is OK", $file_name);
            }
            $moved_ok = $moved_ok + 1;
            $acceptedFilesArray[$moved_ok]["name"] = $file_name;
            $acceptedFilesArray[$moved_ok]["tmp_name"] = $tempfilename;
        }
    }
    // End for
    if ($moved_notok > 0) {
        $errormessage = __("Unable to move the uploaded file to the temp directory.<br /><br />The administrator of this website has to <b>chmod 777</b> the /temp directory of net2ftp.");
        setErrorVars(false, $errormessage, debug_backtrace(), __FILE__, __LINE__);
        return false;
    } elseif ($moved_ok == 0 && $skipped == 0) {
        $errormessage = __("You did not provide any file to upload.");
        setErrorVars(false, $errormessage, debug_backtrace(), __FILE__, __LINE__);
        return false;
    } elseif ($moved_ok == 0 && $skipped > 0) {
        return "all_uploaded_files_are_too_big";
    } else {
        return $acceptedFilesArray;
    }
}
function net2ftp_module_sendHttpHeaders()
{
    // --------------
    // This function sends HTTP headers
    // --------------
    global $net2ftp_settings, $net2ftp_globals, $net2ftp_messages, $net2ftp_result, $net2ftp_output;
    // ------------------------------------
    // 1. Register the global variables
    // ------------------------------------
    if ($net2ftp_globals["screen"] == 2) {
        // Code for old file jupload applet (jupload version 0.86)
        //		$file_counter = 0;
        //		foreach($_FILES as $tagname=>$object) {
        //			if ($object['name'] != "") {
        //				$file_counter = $file_counter + 1;
        //				$uploadedFilesArray["$file_counter"]["name"]               = $object['name'];
        //				$uploadedFilesArray["$file_counter"]["tmp_name"]           = $object['tmp_name'];
        //				$uploadedFilesArray["$file_counter"]["size"]               = $object['size'];
        //				$uploadedFilesArray["$file_counter"]["error"]              = $object['error'];
        //				// Look for special encoded jupload files
        //				$contentType = $object['type'];
        //				if (substr($contentType,0,7) == "jupload") {
        //					$base64_encoded_path = substr($contentType,8);
        //					$base64_decoded_path = base64_decode($base64_encoded_path);
        //					$uploadedFilesArray["$file_counter"]["absolute_directory"] = $base64_decoded_path;
        //				} // end if
        //			} // end if
        //		} // end foreach
        // Code for new file jupload applet (jupload version 5.0.8)
        $file_counter = 0;
        foreach ($_FILES as $tagname => $object) {
            if ($object['name'] != "") {
                $file_counter = $file_counter + 1;
                $uploadedFilesArray["{$file_counter}"]["name"] = $object['name'];
                $uploadedFilesArray["{$file_counter}"]["type"] = $object['type'];
                $uploadedFilesArray["{$file_counter}"]["tmp_name"] = $object['tmp_name'];
                $uploadedFilesArray["{$file_counter}"]["error"] = $object['error'];
                $uploadedFilesArray["{$file_counter}"]["size"] = $object['size'];
                $uploadedFilesArray["{$file_counter}"]["mime"] = validateEntry($_POST["mimetype" . $file_counter]);
                $uploadedFilesArray["{$file_counter}"]["relative_directory"] = validateDirectory($_POST["relpathinfo" . $file_counter]);
                $uploadedFilesArray["{$file_counter}"]["mtime"] = validateEntry($_POST["filemodificationdate" . $file_counter]);
            }
            // end if
        }
        // end foreach
        echo "Please wait, the files are being transferred to the FTP server...<br />\n";
        flush();
        // ------------------------------------
        // 2. POST METHOD: Move files from the *webserver's* temporary directory to *net2ftp's*
        // temporary directory (move_uploaded_files).
        // ------------------------------------
        if ($_SERVER["REQUEST_METHOD"] == "POST" && sizeof($uploadedFilesArray) > 0) {
            $moved_counter = 0;
            for ($j = 1; $j <= sizeof($uploadedFilesArray); $j++) {
                $file_name = $uploadedFilesArray["{$j}"]["name"];
                $file_tmp_name = $uploadedFilesArray["{$j}"]["tmp_name"];
                $file_size = $uploadedFilesArray["{$j}"]["size"];
                $file_error = $uploadedFilesArray["{$j}"]["error"];
                $file_relative_directory = $uploadedFilesArray["{$j}"]["relative_directory"];
                if ($file_name != "" && $file_tmp_name == "" || $file_size > $net2ftp_settings["max_filesize"]) {
                    // The case ($file_name != "" && $file_tmp_name == "") occurs when the file is bigger than the directives set in php.ini
                    // In that case, only $uploadedFilesArray["$j"]["name"] is filled in.
                    echo "WARNING: File <b>{$file_name}</b> skipped: this file is too big.<br />\n";
                    @unlink($file_tmp_name);
                    continue;
                } elseif (checkAuthorizedName($file_name) == false || checkAuthorizedName($file_relative_directory) == false) {
                    echo "WARNING: File <b>{$file_relative_directory}</b> skipped: it contains a banned keyword.<br />\n";
                    $skipped = $skipped + 1;
                    @unlink($file_tmp_name);
                    continue;
                }
                // Create the temporary filename as follows: (from left to right)
                // - Use prefix "upload__", to be able to identify from where this temporary file comes from
                // - Create a random filename
                // - Add the original filename extension, to be able to identify the filetype
                // - Add suffix ".txt" to avoid that the file would be executed on the webserver
                $extension = get_filename_extension($file_name);
                if (substr($file_name, -6) == "tar.gz") {
                    $extension = "tar.gz";
                }
                $tempfilename = tempnam2($net2ftp_globals["application_tempdir"], "upload__", "." . $extension . ".txt");
                if ($tempfilename == false) {
                    // If you get this warning message, you've probably forgotten to chmod 777 the /temp directory
                    echo "WARNING: File <b>{$file_name}</b> skipped: unable to create a temporary file on the webserver.<br />\n";
                    @unlink($file_tmp_name);
                    continue;
                }
                // Move the uploaded file
                $move_uploaded_file_result = move_uploaded_file($uploadedFilesArray["{$j}"]["tmp_name"], $tempfilename);
                if ($move_uploaded_file_result == false) {
                    echo "WARNING: File <b>{$file_name}</b> skipped: unable to move the uploaded file to the webserver's temporary directory.<br />\n";
                    @unlink($file_tmp_name);
                    @unlink($tempfilename);
                    continue;
                } else {
                    $moved_counter = $moved_counter + 1;
                    $acceptedFilesArray["{$moved_counter}"] = $uploadedFilesArray["{$j}"];
                    // Copy all parameters for this file from the $uploadedFilesArray to the $acceptedFilesArray
                    $acceptedFilesArray["{$moved_counter}"]["tmp_name"] = $tempfilename;
                    // Overwrite the old temporary name by the new one
                }
            }
            // end for j
            flush();
        }
        // end if elseif
        // ------------------------------------
        // 3. Move the files from net2ftp's temporary directory to the FTP server.
        // ------------------------------------
        if (sizeof($acceptedFilesArray) == 0 && sizeof($uploadedFilesArray) != 0) {
            echo "WARNING: No files were accepted (see messages above), so nothing will be transferred to the FTP server.<br />\n";
        } elseif (sizeof($acceptedFilesArray) > 0) {
            // ------------------------------
            // 3.1 Open connection
            // ------------------------------
            // Open connection
            echo __("Connecting to the FTP server") . "<br />\n";
            $conn_id = ftp_openconnection();
            if ($net2ftp_result["success"] == false) {
                echo "ERROR: " . $net2ftp_result["errormessage"] . "<br />\n";
                return false;
            }
            // ------------------------------
            // For loop (loop over all the files)
            // ------------------------------
            for ($k = 1; $k <= sizeof($acceptedFilesArray); $k++) {
                $file_name = $acceptedFilesArray["{$k}"]["name"];
                $file_tmp_name = $acceptedFilesArray["{$k}"]["tmp_name"];
                $file_size = $acceptedFilesArray["{$k}"]["size"];
                $file_error = $acceptedFilesArray["{$k}"]["error"];
                $file_relative_directory = $acceptedFilesArray["{$k}"]["relative_directory"];
                $ftpmode = ftpAsciiBinary($file_name);
                if ($ftpmode == FTP_ASCII) {
                    $printftpmode = "FTP_ASCII";
                } elseif ($ftpmode == FTP_BINARY) {
                    $printftpmode = "FTP_BINARY";
                }
                // ------------------------------
                // 3.2 Within the for loop: create the subdirectory if needed
                // ------------------------------
                // Replace Windows-style backslashes \ by Unix-style slashes /
                $file_relative_directory = str_replace("\\", "/", trim($file_relative_directory));
                // Get the names of the subdirectories by splitting the string using slashes /
                $file_subdirectories = explode("/", $file_relative_directory);
                // $targetdirectory contains the successive directories to be created
                $targetdirectory = $net2ftp_globals["directory"];
                // Loop over sizeof()-1 because the last part is the filename itself:
                for ($m = 0; $m < sizeof($file_subdirectories) - 1; $m++) {
                    // Create the targetdirectory string
                    $targetdirectory = glueDirectories($targetdirectory, $file_subdirectories[$m]);
                    // Check if the subdirectories exist
                    if ($targetdirectory != "") {
                        $result = @ftp_chdir($conn_id, $targetdirectory);
                        if ($result == false) {
                            $ftp_mkdir_result = ftp_mkdir($conn_id, $targetdirectory);
                            if ($ftp_mkdir_result == false) {
                                echo "WARNING: Unable to create the directory <b>{$targetdirectory}</b>. The script will try to continue...<br />\n";
                                continue;
                            }
                            echo "Directory {$targetdirectory} created.<br />\n";
                        }
                        // end if
                        flush();
                    }
                    // end if
                }
                // end for m
                // Store the $targetdirectory in the $acceptedFilesArray
                if ($targetdirectory != "" && $targetdirectory != "/") {
                    $acceptedFilesArray["{$k}"]["targetdirectory"] = $targetdirectory;
                }
                // ------------------------------
                // 3.3 Within the for loop: put local file to remote file
                // ------------------------------
                ftp_putfile($conn_id, "", $acceptedFilesArray["{$k}"]["tmp_name"], $acceptedFilesArray["{$k}"]["targetdirectory"], $acceptedFilesArray["{$k}"]["name"], $ftpmode, "move");
                if ($net2ftp_result["success"] == false) {
                    echo "ERROR: File <b>{$file_name}</b> skipped. Message: " . $net2ftp_result["errormessage"] . "<br />\n";
                    setErrorVars(true, "", "", "", "");
                    continue;
                } else {
                    echo "The file <b>{$file_name}</b> was transferred to the FTP server successfully. <br />\n";
                }
                flush();
            }
            // End for k
            // Note: the java applet is looking for the word "SUCCESS" to determine if the upload result is OK or not (see applet parameter stringUploadSuccess)
            // The applet doesn't seem to recognize the words "SUCCESS", "WARNING" or "ERROR" when they are issued by the code above
            echo "SUCCESS";
            // ------------------------------
            // 3.4 Close connection
            // ------------------------------
            ftp_quit($conn_id);
        }
        // end if
    }
    // end if $screen == 2
}
function checkAuthorizedDirectory($directory)
{
    // --------------
    // 1 - This function checks whether the current $directory name contains a banned
    // keyword.
    // 2 - It also checks if the current $directory is a subdirectory of the
    // homedirectory. The rootdirectory is first checked for the current user;
    // if this is not set, the default rootdirectory is checked.
    // --------------
    // -------------------------------------------------------------------------
    // Global variables
    // -------------------------------------------------------------------------
    global $net2ftp_globals, $net2ftp_settings, $net2ftp_result;
    // -------------------------------------------------------------------------
    // 1 - Check if the directory name contains a banned keyword
    // -------------------------------------------------------------------------
    if (checkAuthorizedName($directory) == false) {
        return false;
    }
    // -------------------------------------------------------------------------
    // 2 - Check if the directory is a subdirectory of the homedirectory (set in the DB)
    // -------------------------------------------------------------------------
    // ----------------------------------------------
    // Initial checks
    // ----------------------------------------------
    if ($net2ftp_settings["use_database"] != "yes" || $net2ftp_settings["check_homedirectory"] != "yes") {
        return true;
    }
    // ----------------------------------------------
    // Get the homedirectory from the database, then store it in a global
    // variable, and from then on, don't access the database any more
    // ----------------------------------------------
    $net2ftp_globals["homedirectory"] = getRootdirectory();
    // ----------------------------------------------
    // Check if the current directory is a subdirectory of the homedirectory
    // ----------------------------------------------
    if (isSubdirectory($net2ftp_globals["homedirectory"], $directory) == false) {
        return false;
    } else {
        return true;
    }
}
function net2ftp_module_printBody()
{
    // --------------
    // This function prints the rename screen
    // --------------
    // -------------------------------------------------------------------------
    // Global variables
    // -------------------------------------------------------------------------
    global $net2ftp_settings, $net2ftp_globals, $net2ftp_messages, $net2ftp_result, $net2ftp_output;
    if (isset($_POST["list"]) == true) {
        $list = getSelectedEntries($_POST["list"]);
    } else {
        $list = "";
    }
    if (isset($_POST["newNames"]) == true) {
        $newNames = validateEntry($_POST["newNames"]);
    } else {
        $newNames = "";
    }
    // -------------------------------------------------------------------------
    // Variables for all screens
    // -------------------------------------------------------------------------
    // Title
    $title = __("Rename directories and files");
    // Form name, back and forward buttons
    $formname = "RenameForm";
    $back_onclick = "document.forms['" . $formname . "'].state.value='browse';document.forms['" . $formname . "'].state2.value='main';document.forms['" . $formname . "'].submit();";
    $forward_onclick = "document.forms['" . $formname . "'].submit();";
    // -------------------------------------------------------------------------
    // Variables for screen 1
    // -------------------------------------------------------------------------
    if ($net2ftp_globals["screen"] == 1) {
        // Next screen
        $nextscreen = 2;
    } elseif ($net2ftp_globals["screen"] == 2) {
        // Open connection
        setStatus(2, 10, __("Connecting to the FTP server"));
        $conn_id = ftp_openconnection();
        if ($net2ftp_result["success"] == false) {
            return false;
        }
        // Rename files
        setStatus(4, 10, __("Processing the entries"));
        for ($i = 1; $i <= sizeof($list["all"]); $i++) {
            if (strstr($list["all"][$i]["dirfilename"], "..") != false) {
                $net2ftp_output["rename"][] = __("The new name may not contain any dots. This entry was not renamed to <b>%1\$s</b>", htmlEncode2($newNames[$i])) . "<br />";
                continue;
            }
            if (checkAuthorizedName($newNames[$i]) == false) {
                $net2ftp_output["rename"][] = __("The new name may not contain any banned keywords. This entry was not renamed to <b>%1\$s</b>", htmlEncode2($newNames[$i])) . "<br />";
                continue;
            }
            ftp_rename2($conn_id, $net2ftp_globals["directory"], $list["all"][$i]["dirfilename"], $newNames[$i]);
            if ($net2ftp_result["success"] == false) {
                setErrorVars(true, "", "", "", "");
                $net2ftp_output["rename"][] = __("<b>%1\$s</b> could not be renamed to <b>%2\$s</b>", htmlEncode2($list["all"][$i]["dirfilename"]), htmlEncode2($newNames[$i]));
                continue;
            } else {
                $net2ftp_output["rename"][] = __("<b>%1\$s</b> was successfully renamed to <b>%2\$s</b>", htmlEncode2($list["all"][$i]["dirfilename"]), htmlEncode2($newNames[$i]));
            }
        }
        // End for
        // Close connection
        ftp_closeconnection($conn_id);
    }
    // end elseif
    // -------------------------------------------------------------------------
    // Print the output
    // -------------------------------------------------------------------------
    require_once $net2ftp_globals["application_skinsdir"] . "/" . $net2ftp_globals["skin"] . "/manage.template.php";
}
function ftp_getlist($conn_id, $directory)
{
    // --------------
    // This function connects to the FTP server and returns an array with a list of directories and files.
    // One row per directory or file, with rows from index 1 to n
    //
    // Step 1: send ftp_rawlist request to the FTP server; this returns a string
    // Step 2: parse that string and get a first array ($templist)
    // Step 3: move the rows to another array, to index 1 to n ($list)
    //
    // This function is used in all functions which process directories recursively.
    // --------------
    // -------------------------------------------------------------------------
    // Global variables
    // -------------------------------------------------------------------------
    global $net2ftp_globals, $net2ftp_settings;
    // -------------------------------------------------------------------------
    // Initialization
    // -------------------------------------------------------------------------
    $warnings = "";
    // -------------------------------------------------------------------------
    // Step 1: Chdir to the directory and get the current directory
    // -------------------------------------------------------------------------
    // ----------------------------------------------
    // Step 1a - Directory is "/"
    // Chdir to the directory because otherwise the ftp_rawlist does not work on some FTP servers
    // ----------------------------------------------
    if ($directory == "/") {
        $result1a = @ftp_chdir($conn_id, $directory);
    } elseif ($directory == "") {
        $result1b = @ftp_chdir($conn_id, $directory);
        $directory = @ftp_pwd($conn_id);
    } else {
        // 1c1 - Replace \' by \\' to be able to delete directories with names containing \'
        $directory1 = str_replace("\\'", "\\\\'", $directory);
        // 1c2 - Chdir to the directory
        // This is to check if the directory exists, but also because otherwise
        // the ftp_rawlist does not work on some FTP servers.
        $result1c = @ftp_chdir($conn_id, $directory1);
        // 1c3 - If the first ftp_chdir returns false, try a second time without the leading /
        // Some Windows FTP servers do not work when you use a leading /
        if ($result1c == false) {
            $directory2 = stripDirectory($directory1);
            $result2 = @ftp_chdir($conn_id, $directory2);
            // 1c3 - If the second ftp_chdir also does not work:
            //           For the Browse screen ==> go to the user's root directory
            //           For all other screens ==> return error
            if ($result2 == false) {
                if ($net2ftp_globals["state"] == "browse") {
                    $rootdirectory = getRootdirectory();
                    // User's root directory is different from the current directory, so switch to it
                    if ($directory != $rootdirectory) {
                        $warnings .= __("The directory <b>%1\$s</b> does not exist or could not be selected, so the directory <b>%2\$s</b> is shown instead.", $directory, $rootdirectory);
                        $directory = $rootdirectory;
                        $result3 = @ftp_chdir($conn_id, $directory);
                    } else {
                        $errormessage = __("Your root directory <b>%1\$s</b> does not exist or could not be selected.", $directory);
                        setErrorVars(false, $errormessage, debug_backtrace(), __FILE__, __LINE__);
                    }
                } else {
                    $errormessage = __("The directory <b>%1\$s</b> could not be selected - you may not have sufficient rights to view this directory, or it may not exist.", $directory);
                    setErrorVars(false, $errormessage, debug_backtrace(), __FILE__, __LINE__);
                }
            }
            // end if result2
        }
        // end if result1
    }
    // end if / or "" or else
    // -------------------------------------------------------------------------
    // Step 2 - Get list of directories and files
    // The -a option is used to show the hidden files as well on some FTP servers
    // Some servers do not return anything when using -a, so in that case try again without the -a option
    // -------------------------------------------------------------------------
    $rawlist = ftp_rawlist($conn_id, "-a");
    if (sizeof($rawlist) <= 1) {
        $rawlist = ftp_rawlist($conn_id, "");
    }
    // -------------------------------------------------------------------------
    // Step 3 - Parse the raw list
    // -------------------------------------------------------------------------
    // ----------------------------------------------
    // Initialize variables
    // ----------------------------------------------
    $list["directories"] = array();
    $list["files"] = array();
    $list["symlinks"] = array();
    $list["unrecognized"] = array();
    $directory_index = 1;
    $file_index = 1;
    $symlink_index = 1;
    $unrecognized_index = 1;
    $list["stats"]["directories"]["total_number"] = 0;
    $list["stats"]["directories"]["total_size"] = 0;
    $list["stats"]["directories"]["total_skipped"] = 0;
    $list["stats"]["files"]["total_number"] = 0;
    $list["stats"]["files"]["total_size"] = 0;
    $list["stats"]["files"]["total_skipped"] = 0;
    $list["stats"]["symlinks"]["total_number"] = 0;
    $list["stats"]["symlinks"]["total_size"] = 0;
    $list["stats"]["symlinks"]["total_skipped"] = 0;
    $list["stats"]["unrecognized"]["total_number"] = 0;
    $list["stats"]["unrecognized"]["total_size"] = 0;
    $list["stats"]["unrecognized"]["total_skipped"] = 0;
    // ----------------------------------------------
    // Loop over the raw list lines
    // ----------------------------------------------
    $nr_entries_banned_keyword = 0;
    $nr_entries_too_big = 0;
    for ($i = 0; $i < sizeof($rawlist); $i++) {
        // ----------------------------------------------
        // Scan each line
        // ----------------------------------------------
        $listline = ftp_scanline($directory, $rawlist[$i]);
        // If $listline is empty (e.g. if it contained ".."), continue to the next line
        if ($listline == "") {
            continue;
        }
        // Encode the name for HTML and Javascript
        if (isset($listline["dirfilename"])) {
            $listline["dirfilename_html"] = htmlEncode2($listline["dirfilename"]);
            $listline["dirfilename_url"] = urlEncode2($listline["dirfilename"]);
            $listline["dirfilename_js"] = javascriptEncode2($listline["dirfilename"]);
        }
        // Check if the filename contains a forbidden keyword
        // If it does, then this line will not be selectable on the Browse screen
        // Note: even if "selectable" is set to true here, it can still be set to false just below if the filesize is too big
        if (checkAuthorizedName($listline["dirfilename"]) == true) {
            $listline["selectable"] = "ok";
        } else {
            $listline["selectable"] = "banned_keyword";
            $nr_entries_banned_keyword++;
        }
        // Check if the filesize is bigger than the maximum authorized filesize
        if ($listline["dirorfile"] == "-" && isset($listline["size"]) && is_numeric($listline["size"])) {
            if ($listline["selectable"] == "ok" && $listline["size"] > $net2ftp_settings["max_filesize"]) {
                $listline["selectable"] = "too_big";
                $nr_entries_too_big++;
            }
        }
        // Form the new directory filename and encode it too
        if ($listline["dirorfile"] == "d") {
            $listline["newdir"] = glueDirectories($directory, $listline["dirfilename"]);
            $listline["newdir_html"] = htmlEncode2($listline["newdir"]);
            $listline["newdir_url"] = urlEncode2($listline["newdir"]);
            $listline["newdir_js"] = javascriptEncode2($listline["newdir"]);
        }
        // ----------------------------------------------
        // Depending on if the line contained a directory/file/symlink/unrecognized
        // row, store the result in different variables
        // ----------------------------------------------
        if ($listline["dirorfile"] == "d") {
            $list["directories"][$directory_index] = $listline;
            $directory_index++;
            if (isset($listline["size"]) && is_numeric($listline["size"])) {
                $list["stats"]["directories"]["total_size"] = $list["stats"]["directories"]["total_size"] + $listline["size"];
            } else {
                $list["stats"]["directories"]["total_skipped"] = $list["stats"]["directories"]["total_skipped"] + 1;
            }
        } elseif ($listline["dirorfile"] == "-") {
            $list["files"][$file_index] = $listline;
            $file_index++;
            if (isset($listline["size"]) && is_numeric($listline["size"])) {
                $list["stats"]["files"]["total_size"] = $list["stats"]["files"]["total_size"] + $listline["size"];
            } else {
                $list["stats"]["files"]["total_skipped"] = $list["stats"]["files"]["total_skipped"] + 1;
            }
        } elseif ($listline["dirorfile"] == "l") {
            $list["symlinks"][$symlink_index] = $listline;
            $symlink_index++;
        } elseif ($listline["dirorfile"] == "u") {
            $list["unrecognized"][$unrecognized_index] = $listline;
            $unrecognized_index++;
        }
        // end elseif
    }
    // end for
    // Print a warning message if some directories, files or symlinks contain a banned keyword or if a file is
    // too big to be downloaded
    if ($nr_entries_banned_keyword > 0) {
        $warnings .= __("Entries which contain banned keywords can't be managed using net2ftp. This is to avoid Paypal or Ebay scams from being uploaded through net2ftp.");
        $warnings .= "<br />\n";
    }
    if ($nr_entries_too_big > 0) {
        $warnings .= __("Files which are too big can't be downloaded, uploaded, copied, moved, searched, zipped, unzipped, viewed or edited; they can only be renamed, chmodded or deleted.");
        $warnings .= "<br />\n";
    }
    // Store the warnings and new directory in $list["stats"]
    if (isset($warnings) == true) {
        $list["stats"]["warnings"] = $warnings;
    } else {
        $list["stats"]["warnings"] = "";
    }
    $list["stats"]["newdirectory"] = $directory;
    // Store the statistics
    $list["stats"]["directories"]["total_size_formated"] = formatFilesize($list["stats"]["directories"]["total_size"]);
    $list["stats"]["files"]["total_size_formated"] = formatFilesize($list["stats"]["files"]["total_size"]);
    $list["stats"]["directories"]["total_number"] = $directory_index - 1;
    $list["stats"]["files"]["total_number"] = $file_index - 1;
    $list["stats"]["symlinks"]["total_number"] = $symlink_index - 1;
    $list["stats"]["unrecognized"]["total_number"] = $unrecognized_index - 1;
    // Put everything together in $list["all"]
    $list["all"] = $list["directories"] + $list["files"] + $list["symlinks"] + $list["unrecognized"];
    // -------------------------------------------------------------------------
    // Step 4 - Return the result
    // -------------------------------------------------------------------------
    return $list;
    // -------------------------------------------------------------------------
    // Some documentation:
    // 1 - Some FTP servers return a total on the first line
    // 2 - Some FTP servers return . and .. in their list of directories
    // ftp_scanline does not return those entries.
    // -------------------------------------------------------------------------
    // 1 - After doing some tests on different public FTP servers, it appears that
    // they reply differently to the ftp_rawlist request:
    //      - some FTP servers, like ftp.belnet.be, start with a line summarizing how
    //        many subdirectories and files there are in the current directory. The
    //        real list of subdirectories and files starts on the second line.
    //               [0] => total 15
    //               [1] => drwxr-xr-x 11 BELNET Archive 512 Feb 6 2000 BELNET
    //               [2] => drwxr-xr-x 2 BELNET Archive 512 Oct 29 2001 FVD-SFI
    //      - some other FTP servers, like ftp.redhat.com/pub, start directly with the
    //        list of subdirectories and files.
    //               [0] => drwxr-xr-x 9 ftp ftp 4096 Jan 11 06:34 contrib
    //               [1] => drwxr-xr-x 13 ftp ftp 4096 Jan 29 21:59 redhat
    //               [2] => drwxrwsr-x 6 ftp ftp 4096 Jun 05 2002 up2date
    // 2 - Some FTP servers return "." and ".." as directories. These fake entries
    // have to be eliminated!
    // They would cause infinite loops in the copy/move/delete functions.
    //               [0] => drwxr-xr-x 5 80 www 512 Apr 10 09:39 .
    //               [1] => drwxr-xr-x 16 80 www 512 Apr 9 08:51 ..
    //               [2] => -rw-r--r-- 1 80 www 5647 Apr 9 08:12 _CHANGES_v0.5
    //               [3] => -rw-r--r-- 1 80 www 1239 Apr 9 08:12 _CREDITS_v0.5
}