From 3309431ac70816d5d35090fafc747bbf5374fef1 Mon Sep 17 00:00:00 2001 From: lolcat Date: Thu, 21 Mar 2024 00:19:41 -0400 Subject: [PATCH] first commit --- README.md | 24 +++ listdir.php | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 488 insertions(+) create mode 100644 README.md create mode 100644 listdir.php diff --git a/README.md b/README.md new file mode 100644 index 0000000..748d906 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# Renadexer + +A no-bullshit solution to list your files! Have you ever looked at apache2's directory listing feature and went +>damn, I really want to load and search this list of 100k+ files and folders without killing Firefox + +Look no further!! + +## Features +- Configurable pagination +- Configurable search function with AND, OR and Regex PCRE modes +- Configurable MOTD +- Mimetype detection using magic bytes +- Seek videos, pause downloads and transfer large files with little memory consumption +- Lighter than your average 2009 anorexic altgirl +- Absolutely horrible URL scheme + +## Installation +Requires PHP 8. Drag `listdir.php` on any server that supports PHP. Change the variables at the top of the file and you're set!! + +## Singular piece of shit screenshot +![screenshot](https://i.imgur.com/Q9X9SZ1.png) + +## License +Do whatever the fuck you want license (WTFPL) diff --git a/listdir.php b/listdir.php new file mode 100644 index 0000000..419aa48 --- /dev/null +++ b/listdir.php @@ -0,0 +1,464 @@ +' . + '' . + '' . + '' . $title . '' . + '' . + '' . + '

' . $title . '

' . + '

' . $text . '

' . + '
' . + $motd . + '' . + ''; + die(); +} + +function do_filesize($path, $is_dir){ + + if($is_dir){ + + return null; + } + + $filesize = filesize($path); + + if($filesize === 0){ + + echo "0.00 B"; + } + + $s = ["B", "KB", "MB", "GB", "TB", "PB"]; + $e = floor(log($filesize, 1024)); + + return round($filesize / pow(1024, $e), 2) . " " . $s[$e]; +} + +function do_header($title, $search, $check, $is_search, $script_name, $up){ + + echo + '' . + '' . + '' . + '' . $title . '' . + '' . + '' . + '

' . $title . '

' . + '
' . + '' . + '
' . + '' . + '' . + '' . + '' . + '' . + '' . + '

' . + ($is_search === true ? '< Go back to index

' : "") . + ($up !== false ? '^ Go up

' : "") . + '' . + '' . + ($is_search === false ? '' : "") . + '' . + '' . + '' . + ($is_search === false ? '' : "") . + '' . + '' . + '' . + ''; + +} + +// handle search +if(isset($_GET["query"])){ + + $query = + ( + isset($_GET["query"]) && + !empty(trim($_GET["query"])) && + is_string($_GET["query"]) + ) ? trim($_GET["query"]) : false; + + $filter = + ( + isset($_GET["filter"]) && + ( + $_GET["filter"] == "and" || + $_GET["filter"] == "or" || + $_GET["filter"] == "pcre" + ) + ) ? $_GET["filter"] : "and"; + + $folder_base_strlen = strlen($folder_base); + + if($query === false){ + + do_error( + 400, + "Search query is empty", + "You need to search for something you dumb shit!", + $motd, + $script_name + ); + } + + $query_escaped = htmlspecialchars($query); + + do_header("search results for "" . $query_escaped . """, $query_escaped, $filter, true, $script_name, false); + + // prepare search cmp + $query_arr = + explode( + " ", + preg_replace( + '/ +/', + " ", + $query + ) + ); + + $dir_iterator = new RecursiveDirectoryIterator($folder_base, FilesystemIterator::SKIP_DOTS); + $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST); + + $matches = 0; + while(true){ + + $iterator->next(); + + if(!$iterator->valid()){ + + break; + } + + $filename = $iterator->getFilename(); + + switch($filter){ + + case "and": + $check = true; + foreach($query_arr as $q){ + + if(stripos($filename, $q) === false){ + + $check = false; + break; + } + } + break; + + case "or": + $check = false; + foreach($query_arr as $q){ + + if(stripos($filename, $q) !== false){ + + $check = true; + break; + } + } + break; + + case "pcre": + $match = preg_match($query, $filename); + + if($match === false){ + + if(preg_last_error() !== PREG_NO_ERROR){ + + // regex error + echo + '' . + '
' . + 'type' . + '' . + 'name' . + '' . + 'size' . + '

RegEx error: ' . preg_last_error_msg() . '


' . + $motd . + '' . + ''; + die(); + } + + continue 2; + }elseif($match === 1){ + + $check = true; + }else{ + + $check = false; + } + break; + } + + if($check){ + + $matches++; + $internal_path = $iterator->getPath() . "/" . $filename; + $fullpath = + substr_replace( + $internal_path, + "", + 0, + $folder_base_strlen + ); + + $is_dir = is_dir($internal_path); + + echo + '' . + '' . ($is_dir ? "<DIR>" : "<FILE>") . '' . + '' . + '' . + htmlspecialchars( + $filename + ) . + '' . + '' . + '' . do_filesize($internal_path, $is_dir) . '' . + ''; + } + + if($matches === $max_results){ + + break; + } + } + + // pagination + echo + '
' . + '
Found ' . $matches . ' matches (max=' . $max_results . ')
' . + '
' . + $motd . + '' . + ''; + die(); +} + +$path = + ( + isset($_GET["path"]) && + is_string($_GET["path"]) && + !empty($_GET["path"]) + ) + ? $_GET["path"] : ""; + +$realpath = realpath($folder_base . "/" . $path); + +// file or folder does not exist +if($realpath === false){ + + do_error( + 404, + "Nobody here but us chickens!", + 'Nothing exists under ' . htmlspecialchars("/" . ltrim($path, "/")) . '', + $motd, + $script_name + ); +} + +// path traversal exploit +if(strpos($realpath, $folder_base) !== 0){ + + do_error( + 403, + "Get off my lawn", + 'You do not have access to this shit', + $motd, + $script_name + ); +} + +// handle GETs to files and folders +if(is_dir($realpath)){ + + // handle directory + $page = + ( + isset($_GET["page"]) && + is_numeric($_GET["page"]) && + $_GET["page"] > 0 + ) + ? (int)$_GET["page"] : 1; + + $relative_path = htmlspecialchars("/" . ltrim(str_replace($folder_base, "", $realpath), "/")); + + $iterator = new FilesystemIterator($realpath); + + try{ + $iterator->seek(($page - 1) * $items_per_page); + }catch(OutOfBoundsException){ + + do_error( + 400, + "Out of bounds", + "You requested a page index that does not exist you overweight buffoon", + $motd, + $script_name + ); + } + + if($relative_path == "/"){ + + $up = false; + }else{ + + $up = explode("/", $relative_path); + unset($up[count($up) - 1]); + $up = $script_name . "?path=" . urlencode(implode("/", $up)); + } + + do_header("index of " . $relative_path, "", "and", false, "", $up); + + for($i=0; $i<$items_per_page; $i++){ + + if(!$iterator->valid()){ + + // reached end of file list + break; + } + + $filename = $iterator->getFilename(); + $absolute = $realpath . "/" . $filename; + $is_dir = is_dir($absolute); + + echo + '' . + '' . ($is_dir ? "<DIR>" : "<FILE>") . '' . + '' . + '' . + htmlspecialchars( + $filename + ) . + '' . + '' . + '' . do_filesize($absolute, $is_dir) . + '' . + ''; + + $iterator->next(); + } + + // pagination + echo + '' . + '
' . + '' . + ''; + + // previous page check + if($page !== 1){ + + echo + '' . + '<PREV>' . + ''; + }else{ + + echo '<END>'; + } + + echo '
Page ' . $page . '
'; + + // next page check + $iterator->next(); + if($iterator->valid()){ + + echo + '' . + '<NEXT>' . + ''; + }else{ + + echo '<END>'; + } + + echo + '
' . + $motd . + '' . + ''; + die(); + +}elseif(is_file($realpath)){ + + // handle file + set_time_limit(0); + ob_end_clean(); + + // tell browser you can seek the file + header("Accept-Ranges: bytes"); + header('Content-Disposition: inline; filename="' . rawurlencode(basename($realpath)) . '"'); + + // report right file type + header("Content-Type: " . mime_content_type($realpath)); + + $filesize = filesize($realpath); + + // detect content range + $headers = getallheaders(); + $handle = fopen($realpath, "r"); + + if(isset($headers["Range"])){ + + // do range + preg_match( + '/^bytes=([0-9]*)-/', + $headers["Range"], + $matches + ); + + $range = isset($matches[1]) ? (int)$matches[1] : null; + + if( + $range !== null && + $range >= 0 && + $range < $filesize + ){ + + http_response_code(206); // partial content + header("Content-Range: bytes " . $range . "-" . ($filesize - 1) . "/" . $filesize); + header("Content-Length: " . $filesize - $range); + + fseek($handle, $range); + }else{ + + http_response_code(416); // range not satisfiable + die(); + } + }else{ + + header("Content-Length: " . $filesize); + } + + fpassthru($handle); + die(); + +}else{ + + // what the fuck + do_error( + 400, + "What the fuck", + 'You requested something that is neither a file nor a directory, what the actual fuck', + $motd, + $script_name + ); +} +?>