<?php
/*
* ServerNavigator 1.0
*
* @author: Carlos Reche
* @e-mail: hide@address.com
*
* Dez 20, 2004
*
*/
class ServerNavigator
{
var $start; // (string) Starting dir (relative to script dir)
var $required_password; // (string) Password required before shows the folder content. Leave empty for requiring no passwords.
var $allowed_ip_list; // (array) List of all allowed IPs. Use this method $this->addAllowedIP("111.111.111.___") to create a mask
var $hidden_extensions; // (array) List of file extensions that should be hidden
var $use_image_icons; // (bool) Sets if should use Apache's default icons
var $show_subfolders_size; // (bool) Sets if should get subfolders size (makes the processing slower)
var $script_file; // (string) Script's name
var $root; // (string) Path to root
var $path; // (string) Path to showed dir
var $user_password; // (string) Password typed by the user
// Configuration
var $extensions; // (array) List of all recognized extensions
function ServerNavigator($start = "./", $required_password = "", $allowed_ip_list = array(), $hidden_extensions = array(),
$use_image_icons = true, $show_subfolders_size = false)
{
$this->start = $this->realPath((string)$start);
$this->required_password = (string)$required_password;
$this->allowed_ip_list = (array)$allowed_ip_list;
$this->hidden_extensions = (array)$hidden_extensions;
$this->use_image_icons = (bool)$use_image_icons;
$this->show_subfolders_size = (bool)$show_subfolders_size;
if (isset($_SERVER['SCRIPT_NAME'])) {
$this->script_file = $this->realPath($_SERVER['SCRIPT_NAME']);
}
else if (isset($_SERVER['PHP_SELF'])) {
$this->script_file = $this->realPath($_SERVER['PHP_SELF']);
}
else {
$this->script_file = "#";
$this->error("There were problems during execution.");
}
// Calculates path to root
$levels = count(explode("/", $this->script_file)) - 2;
for ($i = 0, $this->root = ""; $i < $levels; $i++)
{
$this->root .= "../";
}
$this->extensions = array(
'comp' => array('exe', 'dat', 'msi'),
'layout' => array('php', 'asp', 'jsp', 'htm', 'html', 'shtml', 'phtml'),
'image' => array('jpg', 'jpeg', 'gif', 'png', 'bmp'),
'script' => array('js', 'cgi'),
'sound' => array('mp3', 'wav', 'mid', 'au', 'swf'),
'movie' => array('mpg', 'mpeg', 'qt', 'wmv', 'asf', 'mov', 'avi', 'asx'),
'text' => array('doc', 'txt', 'pdf'),
'compressed' => array('zip', 'arj', 'rar', 'tar', 'gz'),
);
}
function showContent($print = true)
{
if (isset($_POST['password']) || !isset($_GET['path']) || !isset($_GET['key']))
{
$path = (isset($_GET['path'])) ? $_GET['path'] : $this->start;
$path = ($path != "") ? $path : "./";
$password = (isset($_POST['password'])) ? $_POST['password'] : "";
$link = $this->script_file . "?path=" . urlencode($path) . "&key=" . $this->encode($password);
if (!headers_sent()) {
header("location: " . $link);
}
else {
echo '<script type="text/javascript">window.location.href=\''.$link.'\';</script>';
echo '<p>Headers already sent, cannot redirect automatically. <a href="' . $link . '">Use this link to proceed</a>.</p>';
}
}
else
{
$this->path = $this->realPath($_GET['path']);
$this->path = ($this->path != "") ? $this->path : "./";
$this->user_password = $_GET['key'];
}
if (count($this->allowed_ip_list) > 0)
{
foreach ($this->allowed_ip_list as $i => $ip)
{
$this->allowed_ip_list[$i] = preg_replace( array("'_'", "'\\.'"), array("\d?", "\\."), $ip);
}
if (!preg_match("/^(" . implode("|", $this->allowed_ip_list) . ")$/", $this->getIP()))
{
return $this->error("You have no permission to access this page!");
}
}
if ($this->required_password != "")
{
if ($this->encode($this->required_password) != $this->user_password)
{
return $this->form(false);
}
}
$dir_list = $file_list = $subdir_size_list = array();
$total_dir_size = 0;
if (($dir_handle = @opendir($this->path)) === false)
{
$this->error("Could NOT open dir: " . $this->path);
return false;
}
while (($file = @readdir($dir_handle)) !== false)
{
if ($file == '.' || $file == '..')
{
continue;
}
if (is_file($this->path . $file))
{
if (in_array( preg_replace("/^.+?\\.(\w{2,4})$/", "\\1", $file) , $this->hidden_extensions))
{
continue;
}
$file_list[] = $file;
$total_dir_size += filesize($this->path . $file);
}
else
{
$dir_list[] = $file;
if ($this->show_subfolders_size)
{
$stack = array($this->path . $file . '/');
$size = 0;
while (count($stack) > 0)
{
$subdir = array_shift($stack);
$subdir_handle = @opendir($subdir);
while (($subdir_file = @readdir($subdir_handle)) !== false)
{
if ($subdir_file == '.' || $subdir_file == '..')
{
continue;
}
if ($this->show_subfolders_size)
if (is_dir($subdir . $subdir_file))
{
array_push($stack, $subdir.$subdir_file.'/');
}
$size += filesize($subdir . $subdir_file);
}
@closedir($subdir_handle);
}
$subdir_size_list[$file] = $size;
$total_dir_size += $size;
}
}
}
@closedir($dir_handle);
natcasesort($dir_list);
natcasesort($file_list);
$total_files = count($dir_list) + count($file_list);
$total_size = $this->formatSize($total_dir_size);
$print_spacer = (count($file_list) > 0 && count($dir_list) > 0) ? true : false;
$page_link = $this->realPath(dirname($this->script_file) . '/' . $this->path);
$heading_path = $this->realPath($_SERVER['HTTP_HOST'] . '/' . $page_link);
$heading_path_parts = explode("/", $heading_path);
$levels = count($heading_path_parts) - 1;
for ($heading_path = ""; $levels > 0; $levels--)
{
for ($i = 1, $path = ""; $i < $levels; $i++) { $path .= "../"; }
$link = $this->realPath($this->path . $path);
$heading_path .= ($path != "") ? ('<a href="' . $this->script_file . '?path=' . urlencode($link) . '&key=' . $this->user_password . '">') : "";
$heading_path .= array_shift($heading_path_parts) . '/';
$heading_path .= ($path != "") ? ('</a>') : "";
}
$html = "\n".' <div id="heading">';
$html .= "\n".' Path: <span class="path">' . $heading_path . '</span>';
$html .= "\n".' <div class="action_links">';
$html .= "\n".' <a href="' . $this->script_file . '?path=' . urlencode($this->path) . '&key=' . $this->user_password . '">Reload</a>';
$html .= "\n".' | <a href="' . $page_link . '">Enter</a>';
$html .= "\n".' </div>';
$html .= "\n".' </div>';
$html .= "\n".' <table cellpadding="5" cellspacing="0" id="files">';
$html .= "\n".' <tr>';
$html .= "\n".' <th class="table_heading_col_1">Total: '.$total_files.' files ('.$total_size.')</th>';
$html .= "\n".' <th class="table_heading_col_2">Size</th>';
$html .= "\n".' <th class="table_heading_col_3">Modified in</th>';
$html .= "\n".' <th class="table_heading_col_4">Created in</th>';
$html .= "\n".' </tr>';
while (($dir = array_shift($dir_list)) !== NULL)
{
if ($this->use_image_icons && file_exists($this->root . '../icons/folder.gif'))
{
$icon = '<img src="/icons/folder.gif" alt="" class="image_icon" />';
}
else
{
$icon = '<span class="icon_dir"> </span>';
}
$link = $this->script_file . '?path=' . urlencode($this->path . $dir . '/') . '&key=' . $this->user_password;
$size = ($this->show_subfolders_size) ? $this->formatSize($subdir_size_list[$dir]) : " ";
$html .= "\n".' <tr>';
$html .= "\n".' <td class="table_col_1">';
$html .= "\n".' <a href="' . $link . '">' . $icon . $dir . '</a>';
$html .= "\n".' </td>';
$html .= "\n".' <td class="table_col_2">';
$html .= "\n".' ' . $size;
$html .= "\n".' </td>';
$html .= "\n".' <td class="table_col_3">';
$html .= "\n".' ' . date("m/d/y | H:i:s", filemtime($this->path . $dir));
$html .= "\n".' </td>';
$html .= "\n".' <td class="table_col_4">';
$html .= "\n".' ' . date("m/d/y | H:i:s", filectime($this->path . $dir));
$html .= "\n".' </td>';
$html .= "\n".' </tr>';
}
if ($print_spacer)
{
$html .= "\n".' <tr class="table_line_spacer">';
$html .= "\n".' <td> </td>';
$html .= "\n".' <td> </td>';
$html .= "\n".' <td> </td>';
$html .= "\n".' <td> </td>';
$html .= "\n".' </tr>';
}
while (($file = array_shift($file_list)) !== NULL)
{
$extension = preg_replace("/^.+?\\.(\w{2,4})$/", "\\1", $file);
if (in_array($extension, $this->extensions['comp'])) {
$icon_file = 'comp.gray.gif';
$icon_style = 'icon_comp';
}
else if (in_array($extension, $this->extensions['layout'])) {
$icon_file = 'layout.gif';
$icon_style = 'icon_layout';
}
else if (in_array($extension, $this->extensions['image'])) {
$icon_file = 'image2.gif';
$icon_style = 'icon_image';
}
else if (in_array($extension, $this->extensions['script'])) {
$icon_file = 'script.gif';
$icon_style = 'icon_script';
}
else if (in_array($extension, $this->extensions['sound'])) {
$icon_file = 'sound1.gif';
$icon_style = 'icon_sound';
}
else if (in_array($extension, $this->extensions['movie'])) {
$icon_file = 'movie.gif';
$icon_style = 'icon_movie';
}
else if (in_array($extension, $this->extensions['text'])) {
$icon_file = 'text.gif';
$icon_style = 'icon_text';
}
else if (in_array($extension, $this->extensions['compressed'])) {
$icon_file = 'compressed.gif';
$icon_style = 'icon_compressed';
} else {
$icon_file = 'generic.gif';
$icon_style = 'icon_generic';
}
if ($this->use_image_icons && file_exists($this->root . '../icons/' . $icon_file))
{
$icon = '<img src="/icons/' . $icon_file . '" alt="" class="image_icon" />';
}
else
{
$icon = '<span class="' . $icon_style . '"> </span>';
}
$html .= "\n".' <tr>';
$html .= "\n".' <td class="table_col_1">';
$html .= "\n".' <a href="' . $this->path . $file . '">' . $icon . $file . '</a>';
$html .= "\n".' </td>';
$html .= "\n".' <td class="table_col_2">';
$html .= "\n".' ' . $this->formatSize(filesize($this->path . $file));
$html .= "\n".' </td>';
$html .= "\n".' <td class="table_col_3">';
$html .= "\n".' ' . date("m/d/y | H:i:s", filemtime($this->path . $file));
$html .= "\n".' </td>';
$html .= "\n".' <td class="table_col_4">';
$html .= "\n".' ' . date("m/d/y | H:i:s", filectime($this->path . $file));
$html .= "\n".' </td>';
$html .= "\n".' </tr>';
}
$html .= "\n".' </table>';
if ($print) {
echo $html;
} else {
return $html;
}
}
function form($print = true)
{
$html = "\n Enter access code:";
$html .= "\n".' <form action="' . $this->script_file . '" method="post">';
$html .= "\n".' <input type="password" name="password" id="password" value="" />';
$html .= "\n".' <input type="submit" id="submit_button" value="enter" />';
$html .= "\n".' </form>';
$html .= "\n".' <script type="text/javascript">document.getElementById("password").focus();</script>';
if ($print) {
echo $html;
} else {
return $html;
}
}
function realPath($path)
{
if ($path == "")
{
return false;
}
$path = trim(preg_replace("/\\\\/", "/", (string)$path));
if (!preg_match("/(\.\w{1,4})$/", $path) && !preg_match("/\?[^\\/]+$/", $path) && !preg_match("/\\/$/", $path))
{
$path .= '/';
}
preg_match_all("/^(\\/|\w:\\/|(http|ftp)s?:\\/\\/[^\\/]+\\/)?(.*)$/i", $path, $matches, PREG_SET_ORDER);
$path_root = $matches[0][1];
$path_dir = $matches[0][3];
$path_dir = preg_replace( array("/^\\/+/", "/\\/+/"), array("", "/"), $path_dir );
$path_parts = explode("/", $path_dir);
for ($i = $j = 0, $real_path_parts = array(); $i < count($path_parts); $i++)
{
if ($path_parts[$i] == '.')
{
continue;
}
else if ($path_parts[$i] == '..')
{
if ( (isset($real_path_parts[$j-1]) && $real_path_parts[$j-1] != '..') || ($path_root != "") )
{
array_pop($real_path_parts);
$j--;
continue;
}
}
array_push($real_path_parts, $path_parts[$i]);
$j++;
}
return $path_root . implode("/", $real_path_parts);
}
/*
* function getIP()
*
* by R. Rajesh Jeba Anbiah
* published at http://www.php.net/getenv, on user's comments
*/
function getIP() {
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) {
$ip = getenv("HTTP_CLIENT_IP");
}
else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) {
$ip = getenv("HTTP_X_FORWARDED_FOR");
}
else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) {
$ip = getenv("REMOTE_ADDR");
}
else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) {
$ip = $_SERVER['REMOTE_ADDR'];
}
else {
$ip = "unknown";
}
return $ip;
}
function formatSize($size_bytes)
{
if ($size_bytes < 1024) {
$size = number_format($size_bytes, 0, ".", ",");
$measure = 'bytes';
}
else if (($size_bytes/1024) < 1024) {
$size = number_format( ($size_bytes/1024) , 2, ".", ",");
$measure = 'KB';
} else if (($size_bytes/(1024*1024)) < 1024) {
$size = number_format( ($size_bytes/(1024*1024)) , 2, ".", ",");
$measure = 'MB';
} else {
$size = number_format( ($size_bytes/(1024*1024*1024)) , 2, ".", ",");
$measure = 'GB';
}
return $size . ' ' . $measure;
}
function encode($string)
{
return md5(sha1($string . date("Ymd") . "@.#;$"));
}
function error($message, $print = true)
{
$error = '<span style="padding: 1px 7px 1px 7px; background-color: #ffd7d7; font-family: verdana; color: #000000; font-size: 13px;"><span style="color: #ff0000; font-weight: bold;">Error!</span> ' . $message . '</span><br /><br /><br />';
if ($print) {
echo $error;
} else {
return $error;
}
}
function show()
{
$body = $this->showContent(false);
$title = $this->realPath($_SERVER['HTTP_HOST'] . '/' . dirname($this->script_file) . '/' . $this->path);
$title = preg_replace("/^.*?\\/?([^\\/]+)\\/?$/", "\\1", $title);
echo '<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ServerNavigator | ' . $title . '</title>
<style type="text/css">
body {
min-width: 650px;
margin: 0px;
padding: 30px 0px;
text-align: center;
}
body, table {
font-family: Verdana;
font-size: 11px;
color: #555;
}
a:link { color: #33c; font-weight: bold; text-decoration: none; }
a:visited { color: #33c; font-weight: bold; text-decoration: none; }
a:hover { color: #c73; text-decoration: none; }
a:active { color: #f00; text-decoration: none; }
.path a:link { color: #023f88; }
.path a:visited { color: #023f88; }
.path a:hover { color: #0099ff; }
.action_links a:link { color: #000; }
.action_links a:visited { color: #000; }
.action_links a:hover { color: #c00; }
#heading {
width: 80%;
margin: 0px auto;
text-align: left;
font-size: 15px;
font-weight: bold;
}
#heading .path { color: #06c; }
#heading .action_links { margin: 10px 20px; word-spacing: 5px; font-size: 11px; font-weight: normal; }
#files {
width: 80%;
margin: 50px auto;
text-align: center;
}
#files td,th { border-bottom: 1px solid #ccc; }
#files .table_heading_col_1 { padding: 5px 0px; }
#files .table_heading_col_2 { padding: 5px 0px; }
#files .table_heading_col_3 { width: 150px; padding: 5px 0px; }
#files .table_heading_col_4 { width: 150px; padding: 5px 0px; }
#files .table_col_1 { padding: 2px 3px; text-align: left; }
#files .table_col_2 { }
#files .table_col_3 { }
#files .table_col_4 { }
#files .table_line_spacer td { height: 30px; padding: 1px 3px 3px 3px; }
.image_icon { margin: 0px 5px; vertical-align: middle; border-width: 0px; }
.icon_dir { background-color: #ffbb00; border: 1px solid #aa7700; width: 22px; font-size: 12px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
.icon_comp { background-color: #cc0000; border: 1px solid #333333; width: 17px; font-size: 15px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
.icon_layout { background-color: #6666dd; border: 1px solid #333333; width: 17px; font-size: 15px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
.icon_image { background-color: #ff9933; border: 1px solid #333333; width: 17px; font-size: 15px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
.icon_script { background-color: #558855; border: 1px solid #333333; width: 17px; font-size: 15px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
.icon_sound { background-color: #00ccaa; border: 1px solid #333333; width: 17px; font-size: 15px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
.icon_movie { background-color: #999999; border: 1px solid #333333; width: 17px; font-size: 15px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
.icon_text { background-color: #ffffaa; border: 1px solid #333333; width: 17px; font-size: 15px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
.icon_compressed { background-color: #ff0033; border: 1px solid #333333; width: 17px; font-size: 15px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
.icon_generic { background-color: #ffffff; border: 1px solid #333333; width: 17px; font-size: 15px; cursor: pointer; margin: 0px 5px; vertical-align: middle; }
</style>
</head>
<body>' . $body . '
</body>
</html>';
}
// Configuration
function setStartingFolder($path)
{
$this->start = $this->realPath((string)$path);
}
function setPassword($password)
{
$this->required_password = (string)$password;
}
function addAllowedIP($ip)
{
foreach (func_get_args() as $arg)
{
if (preg_match("/^([\d\\._]+)$/", trim($arg)))
{
$this->allowed_ip_list[] = (string)$ip;
}
}
}
function hideExtensions($extension)
{
foreach (func_get_args() as $arg)
{
$this->hidden_extensions[] = (string)trim($arg);
}
}
function useImageIcons($should_use = true)
{
$this->use_image_icons = (bool)$should_use;
}
function showSubfoldersSize($should_show = true)
{
$this->show_subfolders_size = (bool)$should_show;
}
}
?>