<?php
/*
 * findex.mini - file lister and browser in php
 * Copyright (C) 2010-2014  ed <tripflag@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License v2
 * (version 2) as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, refer to the following URL:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 */


#if (isset($_GET['dat']) && $_GET['dat']=='sauce') die(highlight_file('index.php'));

function denied(){ die('<h1>403 forbiddena</h1>'); }
function buglol(){ die('<h1>you broke it</h1>'); }
function sploit($m){ die('<h1>you tryin ter sploit me brah</h1><h2>'.$m.'</h2>'); }
function copyerr(){ die('<h2>website owner: you forgot to create or chown the .th directory, see install instructions'); }

header('Content-Type: text/html; charset=UTF-8');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Sat, 09 Jan 2009 09:09:09 GMT');
date_default_timezone_set('UTC');
?><!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8" />
<title>file browser</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=0.5">
<style>
html,body,tr.e,th,td,#list,a {
	color: inherit;
	background: none;
	font-weight: inherit;
	font-size: inherit;
	padding: 0;
	border: none;
}
html {
	color: #ccc;
	background: #333;
	font-family: sans-serif;
	text-shadow: 1px 1px 0px #000;
}
html, body {
	margin: 0;
	padding: 0;
}
body {
	padding-bottom: 2em;
}
#plist {
	color: #aca;
	text-shadow: 1px 1px 0 #000;
	font-variant: small-caps;
	font-weight: normal;
	background: #4c4c4c;
	display: inline-block;
	padding: .2em .5em .2em 1em;
	border-radius: 0 .3em .3em 0;
	box-shadow: .1em .1em .4em #222;
	margin: 1.5em 0;
}
#plist b:after {
	content: '»';
	margin-left: -.4em;
	color: #fff;
}
#plist a {
	padding: .2em .8em;
}
#plist a:last-child {
	color: #fff;
}
#flist {
	border-collapse: collapse;
}
#flist a {
	display: block;
	padding: .3em 0;
}
a {
	color: #fc5;
	padding: .2em;
	text-decoration: none;
}
#flist a span {
	color: #ac5;
	padding-left: 1em;
	display: inline-block;
}
h1 a {
	color: #fff;
	padding: 0 .6em;
	margin: 0 -.2em;
}
tr:nth-child(even) {
	background: none;
}
tr:hover {
	background: #1c1c1c;
}
a:hover {
	color: #fff;
	background: #161616;
}
h1 a:hover {
	background: none;
	text-shadow: 0px 1px 6px #fff;
}
tbody tr.o:first-child {
	display: none;
}
thead th {
	padding: .5em 1.3em .3em 1.3em;
}
thead th+th+th+th {
	background: #444;
	border-radius: .7em 0 0 0;
}
thead a {
	color: #999;
	font-weight: normal;
}
th:nth-child(1) {
	background: #222;
}
tbody,
thead th:nth-child(2) {
	background: #222;
	border-radius: 0 .7em 0 0;
}
tbody {
	width: 100%;
}
td {
	margin: 0;
	padding: 0 .5em;
}
tbody td+td+td {
	font-family: monospace;
	font-size: 1.3em;
	text-align: right;
	padding-right: 1em;
	white-space: nowrap;
}
tbody td:first-child {
	padding-left: 1.5em;
	color: #555;
}
tbody tr:first-child td,
tbody tr.o:first-child+tr td {
	padding-top: .9em;
}
tbody tr:last-child td {
	padding-bottom: 1.3em;
	border-bottom: .5em solid #444;
}

/* ========================================================= */

#mp {
	background: #222;
	display: block;
	width: 10em;
	margin: 0 auto;
	padding: .5em 1.3em;
	border-radius: 0 0 .7em .7em;
}
.play {
	float: left;
	color: #e70;
	padding-right: .5em;
	font-variant: small-caps;
}
.act {
	color: #af0;
}
#mptb,
#mptc {
	height: 2em;
	position: absolute;
	left: 0;
	top: 0;
}
#mpta {
	height: 2em;
	width: 100%;
	position: fixed;
	bottom: 0;
	left: 0;
}
#mptb { background: #000; z-index: 3 }
#mptc { background: #fc5; z-index: 5 }

#blocked {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: #333;
	font-size: 2.5em;
}
#blk_play,
#blk_abrt {
	position: fixed;
	display: table;
	width: 80%;
}
#blk_play {
	height: 60%;
	left: 10%;
	top: 5%;
}
#blk_abrt {
	height: 25%;
	left: 10%;
	bottom: 5%;
}
#blk_play a,
#blk_abrt a {
	display: table-cell;
	vertical-align: middle;
	text-align: center;
	background: #444;
	border-radius: 2em;
}
#blk_tx2 {
	color: #ac5;
}

/* ========================================================= */

@font-face {
	font-family: 'scp';
	src: local('Source Code Pro Regular'), local('SourceCodePro-Regular'), url(/.fim/scp.woff2) format('woff2');
}
#epilogue pre {
	font-family: 'scp', monospace, monospace;
}
#epilogue {
	padding: .2em 1.5em;
}
.dlcode {
	font-size: 2em;
	padding: .5em .5em 0 1em;
	display: block;
}
code {
	color: #f59;
	font-family: monospace, monospace;
}
html pre.line-numbers {
}
html .line-numbers .line-numbers-rows {
	top: -3px;
}

</style></head><body>
<?php

// because php syntax is pig disgusting
function car($a,$b) {return (strncmp($a,$b,strlen($b))===0);}
function cdr($a,$b) {return (strlen($a)>=strlen($b)&&strcmp(substr($a,strlen($b)),$b)===0);}

$dirpath = $_SERVER['REQUEST_URI'];
$dirpath = explode('?',$dirpath);
// extract dirpath, die if illegal format
    if (count($dirpath) == 1) $dirpath = '';
elseif (count($dirpath) == 2) $dirpath = $dirpath[1];
else {
	print_r($dirpath);
	sploit('1)'.$dirpath);
}

//$dirpath = urldecode($dirpath);
$orgpath = $dirpath;
$dirpath = dec($dirpath);
$relpath = $dirpath;
//$abspath = rawurldecode($abspath);
//$pwd = realpath(dirname(__FILE__));
$pwd = get_included_files()[0];
$pwd = realpath(dirname($pwd));
$abspath = realpath($dirpath);

$okay = false;
$safetargets = [ $pwd, '/web/www/foo.moe/.priv/lootbag/done/', '/home/ed/rt-pr/' ];
foreach ($safetargets as $safetarget)
	if (car($abspath, $safetarget))
		$okay = true;

if (!$okay) sploit('2)'.$orgpath);



$ext_code = ['sh','py','vpy','cpp','c','pl','bat','ps1','perl','lua','patch','txt','go','js','ipxe','ahk'];
$fn_code = ['Dockerfile','Makefile'];
if (!is_dir('./'.$dirpath))
{
	$ext = $dirpath;
	$ofs = strrpos($ext, '.');
	if ($ofs !== false)
		$ext = substr($ext, $ofs + 1);
	else
		$ext = '';
	
	$name = '';
	$ofs = strrpos($dirpath, '/');
	if ($ofs !== false)
		$name = substr($dirpath, $ofs + 1);
	
	if (in_array($ext, $ext_code) || in_array($name, $fn_code))
	{
		define('goahead_hl_php', 1);
		require_once('hl.php');
		die();
	}
	
	buglol();
}



if ($dirpath != '')
	$dirpath .= '/';

$listraw = array();
$ptr = @dir('./'.$dirpath) or buglol();
while (($item = $ptr->read()) !== false) {
	if ($item == '.hide' || $item == 'index.html')
		die();
	
	if (car($item, '.')) continue;
	$listraw[] = $item;
}
$ptr->close();
if (true)
{
	//sort($listraw);
	sort($listraw, SORT_NATURAL);
}
else
{
	usort($listraw, function($a,$b)
	{
		return filemtime($a) < filemtime($b);
	});
}

$nope = false;
$dirs = array();
$fils = array();
for ($a=0; $a<count($listraw); $a++) {
	$fn = $listraw[$a];
	$itempath = $dirpath.$fn;
	$add = array(
		'path' => $itempath,
		'name' => $fn,
		'last' => date(
			'Y-m-d, H:i:s',
			filemtime($itempath))
	);
	if (is_dir($itempath)) {
		if (file_exists($itempath.'/.hide'))
			continue;

		$add['size'] = 0;
		$add['type'] = 'Directory';
		$dirs[] = $add;
	} elseif ($fn == 'index.html' || $fn == 'index.php') {
		$nope = $fn;
	} elseif (is_readable($itempath) && !car($fn, 'index.')) {
		$add['type'] = mime_content_type($itempath);
		$add['size'] = 
			filesize($itempath);// / 1024,
			//3, ",", "'") . "kB";
		$fils[] = $add;
	}
}
$list = array_merge($dirs,$fils);

$parent = '';
$pathsc = '';
$paths = explode('/', $dirpath);
array_pop($paths);
echo('<div id="plist"><a href="?">/</a>'."\r\n");
for ($a=0; $a<count($paths); $a++) {
	$parent = $pathsc;
	if ($pathsc != '')
		$pathsc .= '/';
	$pathsc .= $paths[$a];
	echo('<b></b>');
	echo('<a href="?'.enc($pathsc).'">'.$paths[$a].'</a>'."\r\n");
}

echo "</div>";

if (file_exists($dirpath.'.prologue.html'))
{
	echo '<div id="epilogue">';
	readfile($dirpath.'.prologue.html');
	echo '</div>';
}

?>
<table id="flist">
<thead><tr><th></th><th>Filename</th><th sort="int">Size</th><th>Date</th></tr></thead>
<tbody>
<?php

$plink = "?".$parent;
if ($dirpath == "")
	$plink = "..";
echo("<tr><td></td><td><a href=\"{$plink}\">&lt;-- Parent Directory</a></td><td></td><td></td></tr>");

//if ($nope) denied();
if ($nope !== false && $relpath !== '')
{
	$target = $_SERVER['REQUEST_URI'];
	$target = preg_replace('/\?/', '', $target, 1);
	//header('Location: ' . $target);
	echo <<<END

	</tbody></table>
	<h1><a href="{$target}">click me bro</a></h1>
	<script>
		window.location.replace("{$target}");
	</script>
END;
	die();
}

$tags = [];
$fh = @fopen($dirpath.'.tags.txt', 'r');
if ($fh)
{
	while (($line = fgets($fh)) !== false)
	{
		$ofs = strpos($line, ' ');
		if ($ofs === false)
			continue;

		$tags[] = [
			substr($line, 0, $ofs),
			rtrim(substr($line, $ofs + 1))
		];
	}
}

$have_zip = file_exists('index.zip.php');

$sz_sum = 0;
for ($a=0; $a<count($list); $a++)
{
	$i = $list[$a];
	$fn = $i['name'];
	$itempath = $dirpath.$fn;
	$direct = enc($itempath);
	$indirect = '?'.$direct;
	$zip = '&mdash;';

	$ext = $fn;
	$ofs = strrpos($ext, '.');
	if ($ofs !== false)
		$ext = substr($ext, $ofs + 1);
	else
		$ext = '';

	$sz_sum += $i['size'];
	$name = $i['name'];
	$url = $direct;

	$tag = '';
	foreach ($tags as $to)
		if ($name == $to[0])
			$tag = $to[1];
	if ($tag != '')
		$tag = '<span>'.htmlspecialchars($tag).'</span>';

	$hsize = number_format($i['size']);
	
	if ($i['type'] == 'Directory')
	{
		$zip = "DIR";
		
		if (file_exists($itempath."/index.php") || file_exists($itempath."/index.html"))
		{
			// no-op
		}
		else
		{
			$url = $indirect;
			if ($have_zip)
				$zip = "<a href=\"index.zip.php$url\" rel=\"nofollow\">zip</a>";
		}
	}
	elseif (in_array($ext, $ext_code) || in_array($fn, $fn_code))
	{
		$zip = "<a href=\"{$direct}\">DL</a>";
		$url = $indirect;
	}
	
	echo("<tr><td>{$zip}</td><td><a href=\"{$url}\">{$name}{$tag}</a></td>" .
		"<td>{$hsize}</td><td>{$i['last']}</td></tr>\n");
}

function dec($a) { return rawurldecode($a); }
function enc($a) { return str_replace('%2F', '/', rawurlencode($a)); }

$sz_sum = number_format($sz_sum);
echo "<tr><td></td><td>.total</td><td>{$sz_sum}</td><td></td></tr>\n";
echo "</tbody></table>";

if (file_exists($dirpath.'.epilogue.html'))
{
	echo '<div id="epilogue">';
	readfile($dirpath.'.epilogue.html');
	echo '</div>';
}

$jsfile = '/web/www/ocv.me/.fim/index.4.js';
if (file_exists($jsfile))
{
	$jsver = 6;
	//if ($_SERVER['REMOTE_ADDR'] == '84.211.153.58')
	//	$jsver += 1;

	echo "<script src=\"/.fim/index.jq.js\"></script>\n";
	echo "<script src=\"/.fim/index.{$jsver}.js\"></script>\n";
}
?>
</body></html>

