__DIR__ . DIRECTORY_SEPARATOR, 'base_dir' => DIRECTORY_SEPARATOR, 'allowed_types' => ['zip', 'php', 'txt', 'jpg', 'png', 'pdf', 'html', 'css', 'js'], 'max_size' => 10 * 1024 * 1024, 'text_extensions' => ['txt', 'php', 'html', 'css', 'js', 'log', 'ini', 'md', 'csv', 'xml', 'json', 'htaccess'], 'max_view_size' => 5 * 1024 * 1024, ]; $AUTH = [ 'user_hash' => '$2y$11$vloemvW2RzZ4QvgBc0eaEOcVGfyFeqkqgR23avtYsVcc6jlIprYsu', 'pass_hash' => '$2y$11$lL6ABKLcizNyk66UsEFPBOFtB93mW0P/9zmvl8dKAp2iXktfj9BF.', 'session_name' => 'fm_session', 'timeout' => 30 * 60, 'max_attempts' => 5, 'lockout' => 5 * 60, ]; $CONFIG['base_dir'] = rtrim(str_replace(['\\', '/'], DIRECTORY_SEPARATOR, realpath($CONFIG['base_dir']) ?: $CONFIG['base_dir']), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; $CONFIG['script_dir'] = realpath($CONFIG['script_dir']) . DIRECTORY_SEPARATOR; $CONFIG['temp_dir'] = $CONFIG['script_dir'] . 'temp' . DIRECTORY_SEPARATOR; if (!is_dir($CONFIG['temp_dir'])) { @mkdir($CONFIG['temp_dir'], 0755, true); } if (is_dir($CONFIG['temp_dir']) && !is_file($CONFIG['temp_dir'] . '.htaccess')) { @file_put_contents( $CONFIG['temp_dir'] . '.htaccess', "Require all denied\n\nOrder allow,deny\nDeny from all\n\n" ); } function e($value) { return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8'); } function formatSize($bytes) { $bytes = (int) $bytes; if ($bytes <= 0) return '0 B'; $units = ['B', 'KB', 'MB', 'GB', 'TB']; $i = (int) floor(log($bytes, 1024)); $i = min($i, count($units) - 1); return round($bytes / pow(1024, $i), 1) . ' ' . $units[$i]; } function fileExt($name) { return strtolower(pathinfo($name, PATHINFO_EXTENSION)); } function normalizeSeparators($path) { return str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $path); } function relativeTo($absolute, $base_dir) { $rel = strpos($absolute, $base_dir) === 0 ? substr($absolute, strlen($base_dir)) : $absolute; return trim(str_replace(DIRECTORY_SEPARATOR, '/', $rel), '/'); } function securePath($user_path, $base_dir) { $user_path = normalizeSeparators($user_path); $user_path = preg_replace('/\.\.+/', '', $user_path); $full_path = $base_dir . ltrim($user_path, DIRECTORY_SEPARATOR); $real_path = realpath($full_path); if ($real_path === false) { return realpath(dirname($full_path)) === false ? false : $full_path; } if (strpos($real_path . DIRECTORY_SEPARATOR, $base_dir) !== 0) { return false; } return $real_path . (is_dir($real_path) ? DIRECTORY_SEPARATOR : ''); } function insideBase($path, $base_dir) { $real = realpath($path); return $real !== false && strpos($real . DIRECTORY_SEPARATOR, $base_dir) === 0; } function postedItems() { $raw = $_POST['items'] ?? []; if (!is_array($raw)) { $raw = array_filter(array_map('trim', explode(',', (string) $raw)), 'strlen'); } $items = []; foreach ($raw as $item) { $name = basename(trim((string) $item)); if ($name !== '' && $name !== '.' && $name !== '..') { $items[] = $name; } } return array_values(array_unique($items)); } function itemIcon($name, $is_dir = false) { if ($is_dir) { return ['fi-rr-folder', 'ico-folder']; } $map = [ 'zip' => ['fi-rr-file-zipper', 'ico-archive'], 'rar' => ['fi-rr-file-zipper', 'ico-archive'], '7z' => ['fi-rr-file-zipper', 'ico-archive'], 'tar' => ['fi-rr-file-zipper', 'ico-archive'], 'gz' => ['fi-rr-file-zipper', 'ico-archive'], 'jpg' => ['fi-rr-picture', 'ico-image'], 'jpeg' => ['fi-rr-picture', 'ico-image'], 'png' => ['fi-rr-picture', 'ico-image'], 'gif' => ['fi-rr-picture', 'ico-image'], 'webp' => ['fi-rr-picture', 'ico-image'], 'svg' => ['fi-rr-picture', 'ico-image'], 'bmp' => ['fi-rr-picture', 'ico-image'], 'ico' => ['fi-rr-picture', 'ico-image'], 'pdf' => ['fi-rr-file-pdf', 'ico-pdf'], 'doc' => ['fi-rr-file-word', 'ico-doc'], 'docx' => ['fi-rr-file-word', 'ico-doc'], 'xls' => ['fi-rr-file-excel', 'ico-sheet'], 'xlsx' => ['fi-rr-file-excel', 'ico-sheet'], 'csv' => ['fi-rr-file-excel', 'ico-sheet'], 'php' => ['fi-rr-file-code', 'ico-code'], 'js' => ['fi-rr-file-code', 'ico-code'], 'ts' => ['fi-rr-file-code', 'ico-code'], 'json' => ['fi-rr-file-code', 'ico-code'], 'xml' => ['fi-rr-file-code', 'ico-code'], 'css' => ['fi-rr-file-code', 'ico-code'], 'py' => ['fi-rr-file-code', 'ico-code'], 'html' => ['fi-rr-browser', 'ico-code'], 'sql' => ['fi-rr-database', 'ico-code'], 'sh' => ['fi-rr-terminal', 'ico-code'], 'bat' => ['fi-rr-terminal', 'ico-code'], 'mp3' => ['fi-rr-music-alt', 'ico-media'], 'wav' => ['fi-rr-music-alt', 'ico-media'], 'ogg' => ['fi-rr-music-alt', 'ico-media'], 'mp4' => ['fi-rr-video-camera', 'ico-media'], 'avi' => ['fi-rr-video-camera', 'ico-media'], 'mkv' => ['fi-rr-video-camera', 'ico-media'], 'mov' => ['fi-rr-video-camera', 'ico-media'], 'txt' => ['fi-rr-document', 'ico-text'], 'md' => ['fi-rr-document', 'ico-text'], 'log' => ['fi-rr-time-past', 'ico-text'], 'ini' => ['fi-rr-settings-sliders', 'ico-text'], ]; return $map[fileExt($name)] ?? ['fi-rr-file', 'ico-file']; } function result($errors = [], $success = '') { return ['errors' => (array) $errors, 'success' => $success]; } function generateHashesCli(array $argv) { $user = $argv[2] ?? ''; $pass = $argv[3] ?? ''; if ($user === '' || $pass === '') { echo "Uso: php " . basename(__FILE__) . " --hash \"usuario\" \"senha\"\n"; exit(1); } echo "\nCole as duas linhas abaixo no array \$AUTH, no topo deste arquivo:\n\n"; echo " 'user_hash' => '" . password_hash($user, PASSWORD_BCRYPT, ['cost' => 11]) . "',\n"; echo " 'pass_hash' => '" . password_hash($pass, PASSWORD_BCRYPT, ['cost' => 11]) . "',\n\n"; exit(0); } if (PHP_SAPI === 'cli') { if (($argv[1] ?? '') === '--hash') { generateHashesCli($argv); } exit("Abra este arquivo pelo navegador.\n" . "Para gerar novas credenciais: php " . basename(__FILE__) . " --hash \"usuario\" \"senha\"\n"); } function startSecureSession(array $auth) { if (session_status() === PHP_SESSION_ACTIVE) { return; } $https = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') || (int) ($_SERVER['SERVER_PORT'] ?? 0) === 443 || strtolower($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https'; session_name($auth['session_name']); session_set_cookie_params([ 'lifetime' => 0, 'path' => '/', 'httponly' => true, 'secure' => $https, 'samesite' => 'Strict', ]); session_start(); } function agentFingerprint() { return sha1($_SERVER['HTTP_USER_AGENT'] ?? ''); } function csrfToken() { if (empty($_SESSION['fm_csrf'])) { $_SESSION['fm_csrf'] = bin2hex(random_bytes(32)); } return $_SESSION['fm_csrf']; } function csrfValid() { return !empty($_SESSION['fm_csrf']) && is_string($_POST['csrf'] ?? null) && hash_equals($_SESSION['fm_csrf'], $_POST['csrf']); } function csrfField() { return ''; } function lockoutFile(array $auth, $temp_dir) { $ip = $_SERVER['REMOTE_ADDR'] ?? 'local'; return $temp_dir . '.login_' . substr(sha1($ip . '|' . $auth['session_name']), 0, 16) . '.json'; } function loginState(array $auth, $temp_dir) { $file = lockoutFile($auth, $temp_dir); $state = is_file($file) ? json_decode((string) @file_get_contents($file), true) : null; if (!is_array($state)) { $state = ['count' => 0, 'until' => 0]; } if (($state['until'] ?? 0) > 0 && $state['until'] <= time()) { $state = ['count' => 0, 'until' => 0]; @unlink($file); } return $state; } function registerLoginFailure(array $auth, $temp_dir) { $state = loginState($auth, $temp_dir); $state['count'] = ($state['count'] ?? 0) + 1; if ($state['count'] >= $auth['max_attempts']) { $state['until'] = time() + $auth['lockout']; } @file_put_contents(lockoutFile($auth, $temp_dir), json_encode($state)); return $state; } function clearLoginFailures(array $auth, $temp_dir) { @unlink(lockoutFile($auth, $temp_dir)); } function lockoutRemaining(array $state) { return max(0, (int) ($state['until'] ?? 0) - time()); } function isLoggedIn(array $auth) { if (empty($_SESSION['fm_auth'])) { return false; } if (($_SESSION['fm_agent'] ?? '') !== agentFingerprint()) { return false; } if ($auth['timeout'] > 0 && (time() - (int) ($_SESSION['fm_seen'] ?? 0)) > $auth['timeout']) { return false; } $_SESSION['fm_seen'] = time(); return true; } function doLogout() { $_SESSION = []; if (ini_get('session.use_cookies')) { $p = session_get_cookie_params(); setcookie(session_name(), '', time() - 42000, $p['path'], $p['domain'], $p['secure'], $p['httponly']); } session_destroy(); } function renderLoginPage($error = '', $locked_for = 0) { $csrf = csrfToken(); ?> Acesso restrito

Acesso restrito

Entre com suas credenciais para abrir o gerenciador

0): ?>
Muitas tentativas erradas. Novo acesso liberado em minuto(s).
0 ? 'disabled' : '' ?>>
0 ? 'disabled' : '' ?>>
Sessão protegida · credenciais em bcrypt
0) { $login_error = 'Acesso bloqueado temporariamente.'; } elseif (!csrfValid()) { $login_error = 'Sessão expirada. Tente novamente.'; } else { $user_ok = password_verify((string) $_POST['login_user'], $AUTH['user_hash']); $pass_ok = password_verify((string) ($_POST['login_pass'] ?? ''), $AUTH['pass_hash']); if ($user_ok && $pass_ok) { clearLoginFailures($AUTH, $CONFIG['temp_dir']); session_regenerate_id(true); $_SESSION['fm_auth'] = true; $_SESSION['fm_user'] = substr(trim((string) $_POST['login_user']), 0, 64); $_SESSION['fm_seen'] = time(); $_SESSION['fm_agent'] = agentFingerprint(); $_SESSION['fm_csrf'] = bin2hex(random_bytes(32)); header('Location: ' . $_SERVER['REQUEST_URI']); exit; } $state = registerLoginFailure($AUTH, $CONFIG['temp_dir']); $left = max(0, $AUTH['max_attempts'] - $state['count']); $login_error = 'Usuário ou senha inválidos.' . ($left > 0 ? ' Tentativas restantes: ' . $left . '.' : ''); } } renderLoginPage($login_error, lockoutRemaining($state)); } function sendDownloadHeaders($filename, $length, $mime = 'application/octet-stream') { $safe = str_replace(['"', "\r", "\n"], '', $filename); header('Content-Description: File Transfer'); header('Content-Type: ' . $mime); header('Content-Disposition: attachment; filename="' . $safe . '"; filename*=UTF-8\'\'' . rawurlencode($filename)); header('Content-Length: ' . $length); header('Cache-Control: no-cache, must-revalidate'); header('Pragma: public'); } function streamFile($path, $filename, $mime = 'application/octet-stream', $delete_after = false) { while (ob_get_level()) { ob_end_clean(); } sendDownloadHeaders($filename, filesize($path), $mime); readfile($path); if ($delete_after) { @unlink($path); } exit; } function zipAddPath(ZipArchive $zip, $real_path, $entry_name) { if (is_file($real_path)) { return $zip->addFile($real_path, $entry_name) ? 1 : 0; } $count = $zip->addEmptyDir($entry_name) ? 1 : 0; $prefix = strlen($real_path) + 1; $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($real_path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $file) { $sub = str_replace(DIRECTORY_SEPARATOR, '/', substr($file->getPathname(), $prefix)); $entry = $entry_name . '/' . $sub; $ok = $file->isDir() ? $zip->addEmptyDir($entry) : $zip->addFile($file->getPathname(), $entry); if ($ok) $count++; } return $count; } function buildZip(array $items, $zip_path, $current_dir, $base_dir) { if (empty($items)) { return ['error' => 'Nenhum item selecionado.']; } if (!class_exists('ZipArchive')) { return ['error' => 'Extensão ZIP não disponível no servidor.']; } $zip = new ZipArchive(); if ($zip->open($zip_path, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) { return ['error' => 'Não foi possível criar o arquivo ZIP.']; } $count = 0; $warnings = []; foreach ($items as $item) { $item_path = $current_dir . $item; if (!file_exists($item_path)) { $warnings[] = 'Item não encontrado: ' . $item; continue; } if (!insideBase($item_path, $base_dir)) { $warnings[] = 'Acesso negado: ' . $item; continue; } $count += zipAddPath($zip, realpath($item_path), $item); } $zip->close(); if ($count === 0) { @unlink($zip_path); return ['error' => 'Nenhum item pôde ser adicionado ao ZIP.']; } return ['count' => $count, 'warnings' => $warnings]; } function actionCompress(array $items, array $ctx) { $zip_name = 'backup_' . date('Y-m-d_H-i-s') . '_' . substr(md5(uniqid('', true)), 0, 8) . '.zip'; $zip_path = $ctx['temp_dir'] . $zip_name; $zip = buildZip($items, $zip_path, $ctx['current_dir'], $ctx['base_dir']); if (isset($zip['error'])) { return result([$zip['error']]); } $final_path = $ctx['current_dir'] . $zip_name; if (!@rename($zip_path, $final_path)) { @unlink($zip_path); return result(['Erro ao mover o arquivo ZIP para o diretório atual. Verifique as permissões.']); } @chmod($final_path, 0644); $msg = 'Compactação concluída: ' . e($zip_name) . '
' . 'Itens adicionados: ' . (int) $zip['count'] . ' · Tamanho: ' . formatSize(filesize($final_path)); if (!empty($zip['warnings'])) { $msg .= '
Avisos: ' . e(implode('; ', $zip['warnings'])) . ''; } return result([], $msg); } function actionDownloadSelected(array $items, array $ctx) { if (empty($items)) { return result(['Nenhum item selecionado.']); } if (count($items) === 1) { $path = securePath(($ctx['rel_dir'] ? $ctx['rel_dir'] . '/' : '') . $items[0], $ctx['base_dir']); if ($path !== false && is_file($path)) { streamFile($path, $items[0]); } } $zip_name = count($items) === 1 ? $items[0] . '.zip' : 'arquivos_selecionados_' . date('Y-m-d_H-i-s') . '.zip'; $zip_path = $ctx['temp_dir'] . 'download_' . uniqid('', true) . '.zip'; $zip = buildZip($items, $zip_path, $ctx['current_dir'], $ctx['base_dir']); if (isset($zip['error'])) { return result([$zip['error']]); } streamFile($zip_path, $zip_name, 'application/zip', true); } function actionDownload($name, array $ctx) { $filename = basename($name); $filepath = securePath(($ctx['rel_dir'] ? $ctx['rel_dir'] . '/' : '') . $filename, $ctx['base_dir']); if ($filepath === false || !is_file($filepath)) { return result(['Arquivo não encontrado ou acesso negado.']); } streamFile($filepath, $filename); } function actionView($name, array $ctx) { $filename = basename($name); $filepath = securePath(($ctx['rel_dir'] ? $ctx['rel_dir'] . '/' : '') . $filename, $ctx['base_dir']); if ($filepath === false || !is_file($filepath) || !in_array(fileExt($filename), $ctx['text_extensions'], true)) { return result(['Arquivo não encontrado, acesso negado ou não é um arquivo de texto.']); } while (ob_get_level()) { ob_end_clean(); } header('Content-Type: text/plain; charset=utf-8'); header('Content-Disposition: inline; filename="' . str_replace('"', '', $filename) . '"'); if (filesize($filepath) > $ctx['max_view_size']) { echo 'Arquivo muito grande para visualização. Faça o download.'; exit; } readfile($filepath); exit; } function actionCopy(array $post, array $ctx) { $source_name = basename($post['source'] ?? ''); $target_name = basename($post['target'] ?? ''); $target_dir = trim($post['target_dir'] ?? '', '/\\'); if ($source_name === '' || $target_name === '') { return result(['Nome de arquivo inválido.']); } $source_path = securePath(($ctx['rel_dir'] ? $ctx['rel_dir'] . '/' : '') . $source_name, $ctx['base_dir']); $dest_dir_path = securePath($target_dir !== '' ? $target_dir : $ctx['rel_dir'], $ctx['base_dir']); if ($source_path === false || !is_file($source_path) || $dest_dir_path === false || !is_dir($dest_dir_path)) { return result(['Origem ou destino inválido.']); } $target_path = rtrim($dest_dir_path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $target_name; if (file_exists($target_path)) { return result(['O arquivo de destino já existe: ' . $target_name]); } if (!@copy($source_path, $target_path)) { return result(['Erro ao copiar o arquivo. Verifique as permissões.']); } @chmod($target_path, 0644); return result([], 'Arquivo copiado: ' . e($source_name) . '' . e($target_name) . ''); } function actionMkdir($name, array $ctx) { $folder_name = basename(trim((string) $name)); if ($folder_name === '' || $folder_name === '.' || $folder_name === '..') { return result(['Nome de pasta inválido.']); } $new_folder = $ctx['current_dir'] . $folder_name; if (file_exists($new_folder)) { return result(['Esta pasta já existe.']); } if (!@mkdir($new_folder, 0755, true)) { return result(['Erro ao criar a pasta. Verifique as permissões.']); } return result([], 'Pasta criada: ' . e($folder_name) . ''); } function actionDelete($name, array $ctx) { $item_name = basename((string) $name); $item_path = securePath(($ctx['rel_dir'] ? $ctx['rel_dir'] . '/' : '') . $item_name, $ctx['base_dir']); if ($item_path === false || rtrim($item_path, DIRECTORY_SEPARATOR) === rtrim($ctx['base_dir'], DIRECTORY_SEPARATOR)) { return result(['Operação não permitida.']); } if (is_dir($item_path)) { if (count(scandir($item_path)) > 2) { return result(['A pasta não está vazia. Remova os arquivos primeiro.']); } return @rmdir($item_path) ? result([], 'Pasta removida: ' . e($item_name) . '') : result(['Erro ao remover a pasta.']); } if (is_file($item_path)) { return @unlink($item_path) ? result([], 'Arquivo removido: ' . e($item_name) . '') : result(['Erro ao remover o arquivo.']); } return result(['Item não encontrado.']); } function uploadTarget($upload_dir, array $ctx) { $dest = securePath(trim((string) $upload_dir, '/\\'), $ctx['base_dir']); return ($dest === false || !is_dir($dest)) ? $ctx['base_dir'] : $dest; } function actionUrlUpload(array $post, array $ctx) { $url = trim($post['url'] ?? ''); $dest = uploadTarget($post['upload_dir'] ?? '', $ctx); if ($url === '') { return result(['A URL não pode estar vazia.']); } if (!filter_var($url, FILTER_VALIDATE_URL)) { return result(['URL inválida.']); } if (!function_exists('curl_init')) { return result(['cURL não está disponível no servidor.']); } $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 5, CURLOPT_TIMEOUT => 30, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; FileManager/1.0)', ]); $content = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); $curl_error = curl_error($ch); curl_close($ch); if ($curl_error !== '') return result(['Erro cURL: ' . $curl_error]); if ($http_code !== 200) return result(['Erro HTTP: ' . $http_code]); if ($content === '' || $content === false) return result(['Arquivo vazio ou não pôde ser baixado.']); if (strlen($content) > $ctx['max_size']) { return result(['Arquivo muito grande. Máximo: ' . formatSize($ctx['max_size'])]); } $path_parts = pathinfo(parse_url($url, PHP_URL_PATH) ?? ''); $original_name = $path_parts['filename'] ?? 'arquivo'; $file_ext = strtolower($path_parts['extension'] ?? ''); if ($file_ext === '' && $content_type) { $mime_map = [ 'application/zip' => 'zip', 'application/pdf' => 'pdf', 'image/jpeg' => 'jpg', 'image/png' => 'png', 'text/plain' => 'txt', 'text/html' => 'html', 'text/css' => 'css', 'application/json' => 'txt', ]; foreach ($mime_map as $mime => $ext) { if (strpos($content_type, $mime) !== false) { $file_ext = $ext; break; } } } if ($file_ext === '') { $file_ext = 'bin'; } if (!in_array($file_ext, $ctx['allowed_types'], true)) { return result(['Tipo de arquivo não permitido: ' . $file_ext]); } $filename = preg_replace('/[^A-Za-z0-9._-]/', '_', $original_name) . '_' . time() . '.' . $file_ext; $target_path = $dest . $filename; if (@file_put_contents($target_path, $content) === false) { return result(['Erro ao salvar o arquivo.']); } @chmod($target_path, 0644); return result([], 'Arquivo baixado: ' . e($filename) . '
' . 'Tamanho: ' . formatSize(strlen($content)) . ' · Destino: /' . e(relativeTo($dest, $ctx['base_dir']))); } function actionLocalUpload(array $file, array $post, array $ctx) { $dest = uploadTarget($post['upload_dir'] ?? '', $ctx); $file_name = basename($file['name'] ?? ''); $target_file = $dest . $file_name; $file_type = fileExt($target_file); if (!is_uploaded_file($file['tmp_name'] ?? '')) { return result(['Arquivo inválido ou upload interrompido.']); } if ($file['size'] > $ctx['max_size']) { return result(['Arquivo muito grande. Máximo: ' . formatSize($ctx['max_size'])]); } if (!in_array($file_type, $ctx['allowed_types'], true)) { return result(['Tipo de arquivo não permitido: ' . ($file_type ?: 'desconhecido')]); } if (file_exists($target_file)) { return result(['Já existe um arquivo com este nome no destino.']); } if (!move_uploaded_file($file['tmp_name'], $target_file)) { return result(['Erro ao mover o arquivo enviado.']); } @chmod($target_file, 0644); return result([], 'Upload concluído: ' . e($file_name) . '
' . 'Tamanho: ' . formatSize($file['size']) . ' · Destino: /' . e(relativeTo($dest, $ctx['base_dir']))); } $errors = []; $success = ''; $rel_dir = isset($_GET['dir']) ? trim($_GET['dir'], '/\\') : ''; $current_dir = $CONFIG['base_dir']; if ($rel_dir !== '') { $test_dir = securePath($rel_dir, $CONFIG['base_dir']); if ($test_dir !== false && is_dir($test_dir)) { $current_dir = $test_dir; } else { $errors[] = 'Diretório inválido ou acesso negado.'; $rel_dir = ''; } } $display_rel = relativeTo($current_dir, $CONFIG['base_dir']); $ctx = $CONFIG + ['current_dir' => $current_dir, 'rel_dir' => $rel_dir]; $outcome = null; if ($_SERVER['REQUEST_METHOD'] === 'POST' && !csrfValid()) { $errors[] = 'Sessão expirada ou requisição inválida. Recarregue a página e tente novamente.'; } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? ''; if (isset($_POST['delete_item'])) { $outcome = actionDelete($_POST['delete_item'], $ctx); } else { switch ($action) { case 'compress': $outcome = actionCompress(postedItems(), $ctx); break; case 'download_selected': $outcome = actionDownloadSelected(postedItems(), $ctx); break; case 'copy': $outcome = actionCopy($_POST, $ctx); break; case 'mkdir': $outcome = actionMkdir($_POST['folder_name'] ?? '', $ctx); break; case 'delete': $outcome = actionDelete($_POST['item'] ?? '', $ctx); break; case 'upload_url': $outcome = actionUrlUpload($_POST, $ctx); break; default: if (!empty($_FILES['fileToUpload']['name'])) { $outcome = actionLocalUpload($_FILES['fileToUpload'], $_POST, $ctx); } } } } elseif (!empty($_GET['download'])) { $outcome = actionDownload($_GET['download'], $ctx); } elseif (!empty($_GET['view'])) { $outcome = actionView($_GET['view'], $ctx); } if (is_array($outcome)) { $errors = array_merge($errors, $outcome['errors']); $success = $outcome['success']; } function listDirectory($current_dir, $temp_dir) { $entries = @scandir($current_dir); if ($entries === false) { return false; } $dirs = []; $files = []; foreach ($entries as $entry) { if ($entry === '.' || $entry === '..') continue; if ($entry === 'temp' && realpath($current_dir . $entry) === realpath($temp_dir)) continue; $full = $current_dir . $entry; $row = [ 'name' => $entry, 'is_dir' => is_dir($full), 'size' => is_dir($full) ? 0 : (int) @filesize($full), 'modified' => (int) @filemtime($full), ]; if ($row['is_dir']) { $dirs[] = $row; } else { $files[] = $row; } } $by_name = function ($a, $b) { return strnatcasecmp($a['name'], $b['name']); }; usort($dirs, $by_name); usort($files, $by_name); return ['dirs' => $dirs, 'files' => $files, 'all' => array_merge($dirs, $files)]; } function breadcrumbSegments($display_rel) { $segments = []; $acc = ''; foreach (explode('/', trim($display_rel, '/')) as $part) { if ($part === '') continue; $acc .= ($acc === '' ? '' : '/') . $part; $segments[] = ['label' => $part, 'path' => $acc]; } return $segments; } $listing = listDirectory($current_dir, $CONFIG['temp_dir']); $crumbs = breadcrumbSegments($display_rel); $parent_rel = count($crumbs) > 1 ? $crumbs[count($crumbs) - 2]['path'] : ''; $total_dirs = $listing ? count($listing['dirs']) : 0; $total_files = $listing ? count($listing['files']) : 0; $total_size = 0; if ($listing) { foreach ($listing['files'] as $file) { $total_size += $file['size']; } } ?> Gerenciador de Arquivos

Gerenciador de Arquivos

Navegue, envie, compacte e baixe seus arquivos

Não foi possível concluir
Tudo certo
Voltar
Nome Tamanho Modificado Ações
Sem permissão para acessar este diretório.
Esta pasta está vazia.
pasta arquivo

Enviar arquivo do computador

Arraste o arquivo aqui ou clique para selecionar
Máximo · Tipos:
Deixe em branco para salvar na raiz.

Baixar de uma URL (cURL)

O tipo é detectado pela extensão ou pelo Content-Type da resposta.

Informações do ambiente

Upload máximo
Tipos permitidos
cURL
ZipArchive
Diretório base
Local do script
Este script dá acesso total ao sistema de arquivos. Mantenha-o protegido por autenticação e nunca o exponha publicamente.
0 selecionado(s)