function ftp_copymovedelete($conn_id_source, $conn_id_target, $list, $copymovedelete, $divelevel)
{
    // --------------
    // This function copies/moves/deletes directories and files from an FTP server to the same
    // or another FTP server.
    //
    // Note there is a difference between move on the same FTP server, and move to another FTP
    // server. Move on the same FTP server is done by renaming the directories and files because
    // this is much faster.
    //
    // For copy (on same or another FTP server) and move (to another FTP server), files
    // are first transferred from the source FTP server to the webserver, and then transferred
    // to the target FTP server.
    //
    // $list[$i]["dirorfile"] contains d or - which indicates if its a directory or a file
    // $list[$i]["dirfilename"] contains the entry name
    // $list[$i]["sourcedirectory"] contains the source directory
    // $list[$i]["targetdirectory"] contains the target directory
    // $list[$i]["newname"] contains the new name if divelevel = 0; for deeper levels the newname is the entry name itself
    // --------------
    // -------------------------------------------------------------------------
    // Global variables
    // -------------------------------------------------------------------------
    global $net2ftp_globals, $net2ftp_settings, $net2ftp_result, $net2ftp_output;
    // -------------------------------------------------------------------------
    // Initialization
    // -------------------------------------------------------------------------
    if ($divelevel == 0) {
        $net2ftp_output["ftp_copymovedelete"][] = "<ul>";
    }
    // Total number of directories and files on level 0 (chosen by the user)
    $total_dirs_files = $list["stats"]["directories"]["total_number"] + $list["stats"]["files"]["total_number"];
    // -------------------------------------------------------------------------
    // For all directories
    // -------------------------------------------------------------------------
    for ($i = 1; $i <= $list["stats"]["directories"]["total_number"]; $i = $i + 1) {
        // ------------------------------
        // Set the status
        // ------------------------------
        $message = __("Processing entry %1\$s", javascriptEncode2($list["directories"][$i]["dirfilename"])) . " ({$i}/{$total_dirs_files})";
        setStatus($i, $total_dirs_files, $message);
        // ------------------------------
        // Source and target
        // ------------------------------
        $source = glueDirectories($list["directories"][$i]["sourcedirectory"], $list["directories"][$i]["dirfilename"]);
        if ($copymovedelete == "copy" || $copymovedelete == "move") {
            if ($divelevel > 0) {
                $target = glueDirectories($list["directories"][$i]["targetdirectory"], $list["directories"][$i]["dirfilename"]);
            } else {
                $target = glueDirectories($list["directories"][$i]["targetdirectory"], $list["directories"][$i]["newname"]);
            }
            // First-level user-selected directories can have been renamed
        } else {
            $target = "";
        }
        // ------------------------------
        // Print starting message
        // ------------------------------
        $net2ftp_output["ftp_copymovedelete"][] = __("Processing directory <b>%1\$s</b>", $source);
        $net2ftp_output["ftp_copymovedelete"][] = "<ul>";
        // ------------------------------
        // Check that the targetdirectory is not a subdirectory of the sourcedirectory
        // ------------------------------
        if ($conn_id_source == $conn_id_target && $copymovedelete != "delete" && isSubdirectory($source, $target) == true) {
            $net2ftp_output["ftp_copymovedelete"][] = __("The target directory <b>%1\$s</b> is the same as or a subdirectory of the source directory <b>%2\$s</b>, so this directory will be skipped", $target, $source);
            $net2ftp_output["ftp_copymovedelete"][] = "</ul>";
            continue;
        }
        // ------------------------------
        // Check if the directory contains a banned keyword
        // ------------------------------
        // If banned keyword - copy: continue
        // If banned keyword - move: abort
        if ($list["directories"][$i]["selectable"] == "banned_keyword") {
            if ($copymovedelete == "copy") {
                $net2ftp_output["ftp_copymovedelete"][] = __("The directory <b>%1\$s</b> contains a banned keyword, so this directory will be skipped", $source);
                $net2ftp_output["ftp_copymovedelete"][] = "</ul>";
                continue;
            } elseif ($copymovedelete == "move") {
                $net2ftp_output["ftp_copymovedelete"][] = __("The directory <b>%1\$s</b> contains a banned keyword, aborting the move", $source);
                $net2ftp_output["ftp_copymovedelete"][] = "</ul>";
                return false;
            }
        }
        // ------------------------------
        // For copy (to the same or another FTP server), move (to another FTP server) or delete
        // ------------------------------
        if ($copymovedelete == "copy" || $copymovedelete == "move" && $conn_id_source != $conn_id_target || $copymovedelete == "delete") {
            // Create the targetdirectory
            if ($copymovedelete == "copy" || $copymovedelete == "move") {
                $success1 = ftp_mkdir($conn_id_target, $target);
                if ($success1 == false) {
                    $net2ftp_output["ftp_copymovedelete"][] = __("Unable to create the subdirectory <b>%1\$s</b>. It may already exist. Continuing the copy/move process...", $target);
                } else {
                    $net2ftp_output["ftp_copymovedelete"][] = __("Created target subdirectory <b>%1\$s</b>", $target);
                }
            }
            // Get a new list
            $newlist = ftp_getlist($conn_id_source, $source);
            if ($net2ftp_result["success"] == false) {
                $net2ftp_output["ftp_copymovedelete"][] = __("The directory <b>%1\$s</b> could not be selected, so this directory will be skipped", $source);
                $net2ftp_output["ftp_copymovedelete"][] = "</ul>";
                setErrorVars(true, "", "", "", "");
                continue;
            }
            // Add information to the list
            for ($j = 1; $j <= $newlist["stats"]["directories"]["total_number"]; $j++) {
                $newlist["directories"][$j]["sourcedirectory"] = $source;
                $newlist["directories"][$j]["targetdirectory"] = $target;
            }
            for ($j = 1; $j <= $newlist["stats"]["files"]["total_number"]; $j++) {
                $newlist["files"][$j]["sourcedirectory"] = $source;
                $newlist["files"][$j]["targetdirectory"] = $target;
            }
            // Call the function recursively
            $newdivelevel = $divelevel + 1;
            $ftp_copymovedelete_result = ftp_copymovedelete($conn_id_source, $conn_id_target, $newlist, $copymovedelete, $newdivelevel);
            // Delete the source directory
            // (Only if there were no problems in the recursive call to ftp_copymovedelete() above)
            if ($ftp_copymovedelete_result == true && ($copymovedelete == "move" || $copymovedelete == "delete")) {
                ftp_rmdir2($conn_id_source, $source);
                if ($net2ftp_result["success"] == false) {
                    setErrorVars(true, "", "", "", "");
                    $net2ftp_output["ftp_copymovedelete"][] = __("Unable to delete the subdirectory <b>%1\$s</b> - it may not be empty", $source);
                } else {
                    $net2ftp_output["ftp_copymovedelete"][] = __("Deleted subdirectory <b>%1\$s</b>", $source);
                }
            }
        }
        // end if copy, move to another FTP server, delete
        // ------------------------------
        // For move (to the same FTP server)
        // ------------------------------
        if ($copymovedelete == "move" && $conn_id_source == $conn_id_target) {
            ftp_rename3($conn_id_source, $source, $target);
            if ($net2ftp_result["success"] == false) {
                setErrorVars(true, "", "", "", "");
                $net2ftp_output["ftp_copymovedelete"][] = __("Unable to move the directory <b>%1\$s</b>", $source);
                $net2ftp_output["ftp_copymovedelete"][] = "</ul>";
                continue;
            } else {
                $net2ftp_output["ftp_copymovedelete"][] = __("Moved directory <b>%1\$s</b>", $source);
            }
        }
        // end if move to the same FTP server
        // ------------------------------
        // Print ending message
        // ------------------------------
        $net2ftp_output["ftp_copymovedelete"][] = __("Processing of directory <b>%1\$s</b> completed", $source);
        $net2ftp_output["ftp_copymovedelete"][] = "</ul>";
    }
    // end for list_directories
    // -------------------------------------------------------------------------
    // Process the files
    // -------------------------------------------------------------------------
    for ($i = 1; $i <= $list["stats"]["files"]["total_number"]; $i = $i + 1) {
        // ------------------------------
        // Set the status
        // ------------------------------
        $j = $list["stats"]["directories"]["total_number"] + $i;
        $message = __("Processing entry %1\$s", javascriptEncode2($list["files"][$i]["dirfilename"])) . " ({$j}/{$total_dirs_files})";
        setStatus($j, $total_dirs_files, $message);
        // ------------------------------
        // Source and target
        // ------------------------------
        $source = glueDirectories($list["files"][$i]["sourcedirectory"], $list["files"][$i]["dirfilename"]);
        if ($copymovedelete == "copy" || $copymovedelete == "move") {
            if (isset($list["files"][$i]["newname"])) {
                $target = glueDirectories($list["files"][$i]["targetdirectory"], $list["files"][$i]["newname"]);
            } else {
                $target = glueDirectories($list["files"][$i]["targetdirectory"], $list["files"][$i]["dirfilename"]);
            }
        } else {
            $target = "";
        }
        // ------------------------------
        // Check that the target is not the same as the source file
        // ------------------------------
        if ($conn_id_source == $conn_id_target && $target == $source) {
            $net2ftp_output["ftp_copymovedelete"][] = __("The target for file <b>%1\$s</b> is the same as the source, so this file will be skipped", $source);
            continue;
        }
        // ------------------------------
        // Check if the file contains a banned keyword, and if it is not bigger than the limit
        // ------------------------------
        // If banned keyword or too big - copy: continue with the other files
        // If banned keyword or too big - move: abort
        if ($list["files"][$i]["selectable"] == "banned_keyword") {
            if ($copymovedelete == "copy") {
                $net2ftp_output["ftp_copymovedelete"][] = __("The file <b>%1\$s</b> contains a banned keyword, so this file will be skipped", $source);
                continue;
            } elseif ($copymovedelete == "move") {
                $net2ftp_output["ftp_copymovedelete"][] = __("The file <b>%1\$s</b> contains a banned keyword, aborting the move", $source);
                return false;
            }
        } elseif ($list["files"][$i]["selectable"] == "too_big") {
            if ($copymovedelete == "copy") {
                $net2ftp_output["ftp_copymovedelete"][] = __("The file <b>%1\$s</b> is too big to be copied, so this file will be skipped", $source);
                continue;
            } elseif ($copymovedelete == "move") {
                $net2ftp_output["ftp_copymovedelete"][] = __("The file <b>%1\$s</b> is too big to be moved, aborting the move", $source);
                return false;
            }
        }
        // ------------------------------------
        // For copy (to the same or another FTP server) or move (to another FTP server)
        // ------------------------------------
        if ($copymovedelete == "copy" || $copymovedelete == "move" && $conn_id_source != $conn_id_target) {
            // Get file from remote sourcedirectory to local temp directory
            // Don't delete the source file yet
            $localtargetdir = $net2ftp_globals["application_tempdir"];
            $localtargetfile = $list["files"][$i]["dirfilename"] . ".txt";
            $remotesourcedir = $list["files"][$i]["sourcedirectory"];
            $remotesourcefile = $list["files"][$i]["dirfilename"];
            $ftpmode = ftpAsciiBinary($list["files"][$i]["dirfilename"]);
            $copymove = "copy";
            ftp_getfile($conn_id_source, $localtargetdir, $localtargetfile, $remotesourcedir, $remotesourcefile, $ftpmode, $copymove);
            if ($net2ftp_result["success"] == false) {
                setErrorVars(true, "", "", "", "");
                if ($copymovedelete == "copy") {
                    $net2ftp_output["ftp_copymovedelete"][] = __("Unable to copy the file <b>%1\$s</b>", $list["files"][$i]["dirfilename"]);
                    continue;
                } elseif ($copymovedelete == "move") {
                    $net2ftp_output["ftp_copymovedelete"][] = __("Unable to move the file <b>%1\$s</b>, aborting the move", $list["files"][$i]["dirfilename"]);
                    return false;
                }
            }
            // Put file from local temp directory to remote targetdirectory
            // Delete the temporary file
            $localsourcedir = $net2ftp_globals["application_tempdir"];
            $localsourcefile = $list["files"][$i]["dirfilename"] . ".txt";
            $remotetargetdir = $list["files"][$i]["targetdirectory"];
            if (isset($list["files"][$i]["newname"])) {
                $remotetargetfile = $list["files"][$i]["newname"];
            } else {
                $remotetargetfile = $list["files"][$i]["dirfilename"];
            }
            $copymove = "move";
            ftp_putfile($conn_id_target, $localsourcedir, $localsourcefile, $remotetargetdir, $remotetargetfile, $ftpmode, $copymove);
            if ($net2ftp_result["success"] == false) {
                setErrorVars(true, "", "", "", "");
                if ($copymovedelete == "copy") {
                    $net2ftp_output["ftp_copymovedelete"][] = __("Unable to copy the file <b>%1\$s</b>", $list["files"][$i]["dirfilename"]);
                    continue;
                } elseif ($copymovedelete == "move") {
                    $net2ftp_output["ftp_copymovedelete"][] = __("Unable to move the file <b>%1\$s</b>, aborting the move", $list["files"][$i]["dirfilename"]);
                    return false;
                }
            } elseif ($net2ftp_result["success"] == true && $copymovedelete == "copy") {
                $net2ftp_output["ftp_copymovedelete"][] = __("Copied file <b>%1\$s</b>", $list["files"][$i]["dirfilename"]);
            } elseif ($copymovedelete == "move") {
                $remotesource = glueDirectories($list["files"][$i]["sourcedirectory"], $list["files"][$i]["dirfilename"]);
                ftp_delete2($conn_id_source, $remotesource);
                if ($net2ftp_result["success"] == false) {
                    setErrorVars(true, "", "", "", "");
                    $net2ftp_output["ftp_copymovedelete"][] = __("Unable to move the file <b>%1\$s</b>", $list["files"][$i]["dirfilename"]);
                } else {
                    $net2ftp_output["ftp_copymovedelete"][] = __("Moved file <b>%1\$s</b>", $list["files"][$i]["dirfilename"]);
                }
            }
        } elseif ($copymovedelete == "move" && $conn_id_source == $conn_id_target) {
            ftp_rename3($conn_id_source, $source, $target);
            if ($net2ftp_result["success"] == false) {
                setErrorVars(true, "", "", "", "");
                $net2ftp_output["ftp_copymovedelete"][] = __("Unable to move the file <b>%1\$s</b>", $source);
            } else {
                $net2ftp_output["ftp_copymovedelete"][] = __("Moved file <b>%1\$s</b>", $source);
            }
        } elseif ($copymovedelete == "delete") {
            $remotesource = glueDirectories($list["files"][$i]["sourcedirectory"], $list["files"][$i]["dirfilename"]);
            ftp_delete2($conn_id_source, $remotesource);
            if ($net2ftp_result["success"] == false) {
                setErrorVars(true, "", "", "", "");
                $net2ftp_output["ftp_copymovedelete"][] = __("Unable to delete the file <b>%1\$s</b>", $list["files"][$i]["dirfilename"]);
                continue;
            } else {
                $net2ftp_output["ftp_copymovedelete"][] = __("Deleted file <b>%1\$s</b>", $list["files"][$i]["dirfilename"]);
            }
        }
        // end delete
    }
    // end for list_files
    if ($divelevel == 0) {
        $net2ftp_output["ftp_copymovedelete"][] = "</ul>";
    }
    // Print message
    if ($divelevel == 0) {
        $net2ftp_output["ftp_copymovedelete"][] = __("All the selected directories and files have been processed.");
    }
    return true;
}
function net2ftp_module_printBody()
{
    // --------------
    // This function prints the copy/move/delete 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["ftpserver2"]) == true) {
        $net2ftp_globals["ftpserver2"] = validateFtpserver($_POST["ftpserver2"]);
    } else {
        $net2ftp_globals["ftpserver2"] = "";
    }
    if (isset($_POST["ftpserverport2"]) == true) {
        $net2ftp_globals["ftpserverport2"] = validateFtpserverport($_POST["ftpserverport2"]);
    } else {
        $net2ftp_globals["ftpserverport2"] = "";
    }
    if (isset($_POST["username2"]) == true) {
        $net2ftp_globals["username2"] = validateUsername($_POST["username2"]);
    } else {
        $net2ftp_globals["username2"] = "";
    }
    if (isset($_POST["password2"]) == true) {
        $net2ftp_globals["password2"] = validatePassword($_POST["password2"]);
    } else {
        $net2ftp_globals["password2"] = "";
    }
    // -------------------------------------------------------------------------
    // Variables for all screens
    // -------------------------------------------------------------------------
    // Title
    if ($net2ftp_globals["state2"] == "copy") {
        $title = __("Copy directories and files");
    } elseif ($net2ftp_globals["state2"] == "move") {
        $title = __("Move directories and files");
    } elseif ($net2ftp_globals["state2"] == "delete") {
        $title = __("Delete directories and files");
    }
    // Form name, back and forward buttons
    $formname = "CopyMoveDeleteForm";
    $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 to the source server
        // ---------------------------------------
        setStatus(2, 10, __("Connecting to the FTP server"));
        $conn_id_source = ftp_openconnection();
        if ($net2ftp_result["success"] == false) {
            return false;
        }
        // ---------------------------------------
        // Open connection to the target server, if it is different from the source server, or if the username
        // is different (different users may have different authorizations on the same FTP server)
        // ---------------------------------------
        if (($net2ftp_globals["ftpserver2"] != "" || $net2ftp_globals["username2"] != "") && ($net2ftp_globals["ftpserver2"] != $net2ftp_globals["ftpserver"] || $net2ftp_globals["username2"] != $net2ftp_globals["username"])) {
            $conn_id_target = ftp_openconnection2();
            // Note: ftp_openconnection2 cleans the input values
            if ($net2ftp_result["success"] == false) {
                return false;
            }
        } else {
            $conn_id_target = $conn_id_source;
        }
        // ---------------------------------------
        // Copy, move or delete the files and directories
        // ---------------------------------------
        ftp_copymovedelete($conn_id_source, $conn_id_target, $list, $net2ftp_globals["state2"], 0);
        // ---------------------------------------
        // Close the connection to the source server
        // ---------------------------------------
        ftp_closeconnection($conn_id_source);
        // ---------------------------------------
        // Close the connection to the target server, if it is different from the source server
        // ---------------------------------------
        if ($conn_id_source != $conn_id_target) {
            ftp_closeconnection($conn_id_target);
        }
    }
    // end elseif
    // -------------------------------------------------------------------------
    // Print the output
    // -------------------------------------------------------------------------
    require_once $net2ftp_globals["application_skinsdir"] . "/" . $net2ftp_globals["skin"] . "/manage.template.php";
}