From 3c210a533ec1ae1447fb4bdc60b59c2379e6d6f7 Mon Sep 17 00:00:00 2001 From: flash Date: Sun, 15 Sep 2024 17:08:58 +0000 Subject: [PATCH] v1 of the abyss directory list script --- abysslistv1.php | 616 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 616 insertions(+) create mode 100644 abysslistv1.php diff --git a/abysslistv1.php b/abysslistv1.php new file mode 100644 index 0000000..bb7e487 --- /dev/null +++ b/abysslistv1.php @@ -0,0 +1,616 @@ + 'page_white_code', + 'js' => 'script_code', + 'sql' => 'page_white_database', + 'ftm' => 'music', + + 'htm' => 'page_white_code', + 'html' => 'page_white_code', + 'text/html' => 'page_white_code', + + 'xml' => 'page_white_code', + 'text/xml' => 'page_white_code', + + 'png' => 'image', + 'jpg' => 'image', + 'jpeg' => 'image', + 'gif' => 'image', + 'ico' => 'image', + 'bmp' => 'image', + 'image/png' => 'image', + 'image/jpeg' => 'image', + 'image/gif' => 'image', + 'image/x-icon' => 'image', + 'image/vnd.microsoft.icon' => 'image', + + 'ttf' => 'font', + 'application/font-sfnt' => 'font', + + 'php' => 'page_white_php', + 'text/x-php' => 'page_white_php', + + 'zip' => 'page_white_zip', + '7z' => 'page_white_zip', + 'rar' => 'page_white_zip', + 'xz' => 'page_white_zip', + 'application/x-7z-compressed' => 'page_white_zip', + 'application/x-xz' => 'page_white_zip', + 'application/x-rar' => 'page_white_zip', + 'application/zip' => 'page_white_zip', + + 'txt' => 'page_white_text', + 'text/plain' => 'page_white_text', + + 'msi' => 'application_xp', + 'exe' => 'application_xp', + 'application/x-dosexec' => 'application_xp', + 'application/x-msi' => 'application_xp', + + 'cab' => 'box', + 'themepack' => 'box', + 'application/vnd.ms-cab-compressed' => 'box', + 'application/x-windows-themepack' => 'box', + + 'iso' => 'page_white_cd', + 'application/x-iso9660-image' => 'page_white_cd', + + 'mkv' => 'film', + 'mp4' => 'film', + 'm4v' => 'film', + 'video/mp4' => 'film', + 'rm' => 'film', + + 'pdf' => 'page_white_acrobat', + 'application/pdf' => 'page_white_acrobat', + + 'swf' => 'page_white_flash', + + 'ogg' => 'music', + 'audio/ogg' => 'music', + 'mid' => 'music', +]); + +function flGetIcon(string $path, bool $skipSpecial = false): string { + if(is_dir($path)) { + if($path !== '..') { + $icoPath = $path . '/_dir.ico'; + if(is_file($icoPath)) + return FL_ICON_ICO . $icoPath; + + $icoPath = $path . '/_icon.txt'; + if(is_file($icoPath)) { + $icoName = trim(file_get_contents($icoPath)); + if($icoName !== '') + return $icoName; + } + } + + return FL_ICON_DIR; + } + + $mime = @mime_content_type($path); + + if(!$skipSpecial) { + if(in_array($mime, FL_ICON_ICE)) + return FL_ICON_ICO . $path; + + if(in_array($mime, FL_ICON_EXW)) + return FL_ICON_EXP . $path; + } + + $name = array_key_exists($mime, FL_ICON_MAP) ? FL_ICON_MAP[$mime] : ''; + if($name !== '') + return $name; + + $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION)); + if($ext === '') + return FL_ICON_DEF; + + if(!$skipSpecial) { + if(in_array($ext, FL_ICON_ICE)) + return FL_ICON_ICO . $path; + + if(in_array($ext, FL_ICON_EXW)) + return FL_ICON_EXP . $path; + } + + // for split archives + if(ctype_digit($ext)) + return FL_ICON_ARC; + + if(array_key_exists($ext, FL_ICON_MAP)) + return FL_ICON_MAP[$ext]; + + return FL_ICON_DEF; +} + +function flGetIconPath(string $name): string { + if(str_starts_with($name, FL_ICON_ICO)) + return '/' . substr($name, strlen(FL_ICON_ICO)); + + if(str_starts_with($name, FL_ICON_EXP)) + return sprintf(FL_ICON_EXE, substr($name, strlen(FL_ICON_EXP))); + + return sprintf(FL_ICON_FMT, $name); +} + +function flGetIconAlt(string $name): string { + if(str_starts_with($name, FL_ICON_ICO)) + return FL_ICON_ICD; + + if(str_starts_with($name, FL_ICON_EXP)) + return FL_ICON_EXD; + + return $name; +} + +function flPathClean(string $path): string { + return trim(parse_url(rawurldecode($path), PHP_URL_PATH), FL_DIR_SEP); +} + +function flPathExplode(string $path): array { + return explode(FL_DIR_SEP, $path); +} + +function flPathImplode(array $parts): string { + return implode(FL_DIR_SEP, $parts); +} + +function flPathResolveAbsolute(array $parts): array { + $absParts = []; + + foreach($parts as $part) { + if($part === '.') + continue; + else if($part === '..') + array_pop($absParts); + else + $absParts[] = $part; + } + + return $absParts; +} + +function flPathEnsureAbsolute(array $parts): bool { + foreach($parts as $part) + if($part === '.' || $part === '..') + return false; + + return true; +} + +if(isset($_GET['_flst_pe_ico']) && is_string($_GET['_flst_pe_ico'])) { + $flExePathParts = flPathExplode(flPathClean($_GET['_flst_pe_ico'])); + if(!flPathEnsureAbsolute($flExePathParts)) { + http_response_code(404); + exit; + } + + $flExePath = FL_ROOT . FL_DIR_SEP . flPathImplode($flExePathParts); + if(!is_file($flExePath)) { + http_response_code(404); + exit; + } + + $output = shell_exec('wrestool -x -t14 ' . escapeshellarg($flExePath)); + if(empty($output)) { + $iconName = FL_ICON_MAP[pathinfo($flExePath, PATHINFO_EXTENSION)] ?? FL_ICON_DEF; + header('Location: ' . sprintf(FL_ICON_FMT, $iconName)); + exit; + } + + header('Content-Type: image/x-icon'); + echo $output; + exit; +} + +if(isset($_GET['_flst_swf']) && is_string($_GET['_flst_swf'])) { + $swfPath = htmlspecialchars(trim($_GET['_flst_swf'], '/')); + $baseName = basename($swfPath); + echo << + + + + {$baseName} + + + +
+ + + + +HTML; + return; +} + +if(isset($_GET['_flst_asset']) && is_string($_GET['_flst_asset'])) { + $flAssetName = $_GET['_flst_asset']; + unset($flAssetBody, $flAssetType); + + if($flAssetName === 'style.css') { + $flAssetType = 'text/css; charset=utf-8'; + $flAssetBody = << .entry-mod, +div > .entry-size { + text-align: left; +} +@media (max-width: 700px) { + .entry-mod, + .entry-size { + display: none; + } +} + +EOF; + } + + + if(isset($flAssetBody)) { + // todo: cache control + http_response_code(200); + + header('Content-Disposition: inline; filename="' . $flAssetName . '"'); + if(isset($flAssetType)) { + header('Content-Type: ' . $flAssetType); + } + + echo $flAssetBody; + } else { + http_response_code(404); + } + exit; +} + +$flRoot = FL_ROOT . FL_DIR_SEP; +$flForceBrowse = FL_ALLOW_PATH_INFO && !empty($_GET['browse']); +$flServerKey = FL_ALLOW_PATH_INFO && substr($_SERVER['REQUEST_URI'], 0, strlen($_SERVER['SCRIPT_NAME'])) === $_SERVER['SCRIPT_NAME'] ? 'PATH_INFO' : 'REQUEST_URI'; +$flLocationNeedsPrefix = $flForceBrowse || $flServerKey === 'PATH_INFO'; +$flLocationPrefix = $flLocationNeedsPrefix ? $_SERVER['SCRIPT_NAME'] : ''; + +$flOriginalLocation = flPathClean( + isset($_GET['path']) && is_string($_GET['path']) + ? $_GET['path'] + : $_SERVER[$flServerKey] +); + +$flLocationParts = flPathExplode($flOriginalLocation); +$flLocationAbsolute = flPathImplode(flPathResolveAbsolute($flLocationParts)); +$flLocation = flPathImplode($flLocationParts); + +if($flLocation !== $flLocationAbsolute) { + header(sprintf('Location: %s%s%s', $flLocationPrefix, FL_DIR_SEP, $flLocationAbsolute)); + exit; +} + +$flLocationParent = dirname($flLocation); +$flFullLocation = rtrim($flRoot . $flLocation, '/'); +$flHeaderFile = $flFullLocation . '/_header.html'; + +if(!is_dir($flFullLocation)) { + http_response_code(404); + echo 'Not Found'; + exit; +} + +$flDirs = []; +$flFiles = []; + +foreach(glob($flFullLocation . '/*') as $entry) { + $entryRelative = substr($entry, strlen($flRoot)); + if(in_array($entryRelative, FL_HIDDEN_PATH)) + continue; + + $isDir = is_dir($entry); + if($isDir && is_file($entryRelative . '/_hidden.txt')) + continue; + + $info = [ + 'type' => $isDir ? 'dir' : (is_file($entry) ? 'fil' : 'unk'), + 'path' => $entryRelative, + 'path_full' => $entry, + 'name' => basename($entry), + ]; + + if($info['type'] === 'fil') { + $info['size'] = filesize($entry); + $info['ext'] = strtolower(pathinfo($entry, PATHINFO_EXTENSION)); + $info['mod'] = filemtime($entry); + + if($info['ext'] === 'swf') + $info['path'] = '?_flst_swf=' . rawurlencode($info['path']); + } + + if($info['type'] === 'dir') { + $info['index'] = !(is_file($entry . '/index.php') || is_file($entry . '/index.html')); + $flDirs[] = $info; + } else + $flFiles[] = $info; +} + +function sort_insensitive($a, $b) { return strcmp(strtolower($a['path']), strtolower($b['path'])); } +usort($flDirs, 'sort_insensitive'); +usort($flFiles, 'sort_insensitive'); + +$flEntries = array_merge($flDirs, $flFiles); + +function flByteSymbol(int $bytes, bool $decimal = true, array $symbols = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']): string { + if($bytes < 1) + return 'Zero Bytes'; + + $divider = $decimal ? 1000 : 1024; + $exp = floor(log($bytes) / log($divider)); + $bytes = $bytes / pow($divider, floor($exp)); + $symbol = $symbols[$exp]; + + return sprintf("%.2f %s%sB", $bytes, $symbol, $symbol !== '' && !$decimal ? 'i' : ''); +} + +function flBuildListingEntry(array $columns, string $linkTarget = ''): string { + $eEntries = []; + + foreach($columns as $name => $body) + $eEntries[] = sprintf('
%s
', $name, $body); + + return sprintf( + "<%1\$s class=\"entry\"%2\$s>\r\n%3\$s\r\n
\r\n", + $linkTarget === '' ? 'div' : 'a', + $linkTarget === '' ? '' : sprintf(' href="%s"', $linkTarget), + implode("\r\n", $eEntries) + ); +} + +function flBuildListingFileEntry($item): string { + return ''; +} + +function flBuildListing(array $columns, array $items): string { + // columns -> [name, title, itemKey, itemFormat] + + $header = []; + foreach($columns as $column) + $header[$column['name']] = $column['title']; + $lEntries = [flBuildListingEntry($header)]; + + foreach($items as $item) + $lEntries[] = flBuildListingFileEntry($item); + + return sprintf("
\r\n%s\r\n
", implode("\r\n", $lEntries)); +} +?> + + + + + <?=(empty($flLocation) ? FL_TITLE : ('/' . $flLocation . ' - ' . FL_TITLE));?> + + + + +
+ +

[] ' . $flLocationPart . ''; } ?>

+ +
+ +
+
+
+
Name
+
Size
+
Last modified
+
+
+ + +
<?=flGetIconAlt($iconName);?>
+
../
+
+
+
+
+ + +
+ <?=flGetIconAlt($iconName);?> +
+
+
+
+
+
+ +
+ + + +