Location: PHPKode > scripts > Server Navigator > server-navigator/class.servernavigator.php
<?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) . '&amp;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) . '&amp;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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>';
            }

            $link = $this->script_file . '?path=' . urlencode($this->path . $dir . '/') . '&amp;key=' . $this->user_password;
            $size = ($this->show_subfolders_size)  ?  $this->formatSize($subdir_size_list[$dir])  :  "&nbsp;";


            $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>&nbsp;</td>';
            $html .= "\n".'        <td>&nbsp;</td>';
            $html .= "\n".'        <td>&nbsp;</td>';
            $html .= "\n".'        <td>&nbsp;</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 . '">&nbsp;&nbsp;&nbsp;</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;
    }

}



?>
Return current item: Server Navigator