Wersja oryginalna.

This commit is contained in:
Nemcio
2019-09-28 04:55:48 +02:00
parent 2d9ca4a314
commit 37487930f4
225 changed files with 11162 additions and 0 deletions

2
.htpasswd.autoindex Executable file
View File

@@ -0,0 +1,2 @@
admin d033e22ae348aeb5660fc2140aec35850c4da997 3
user 12dea96fec20593566ab75692c9949596833adc9 1

161
change_log.html Executable file
View File

@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>AutoIndex PHP Script: Change Log</title>
<style type="text/css" title="AutoIndex Default">
html, body
{
font-family: verdana, lucidia, sans-serif;
font-size: 13px;
background-color: #F0F0F0;
color: #000000;
}
h4, h5
{
text-align: center;
color: #000000;
}
a
{
color: #000000;
text-decoration: none;
}
#main
{
padding-left: 6px;
border: 1px solid #7F8FA9;
background: #F2F6FC;
color: #000020;
font-family: lucida console, sans-serif;
font-size: 12px;
}
</style>
</head>
<body>
<h4>
<a href="http://autoindex.sourceforge.net">AutoIndex PHP Script</a>,
by <a href="mailto:JustinHagstrom [at] yahoo [dot] com">Justin Hagstrom</a>
</h4>
<h5>
Change Log
</h5>
<p>
&nbsp;
</p>
<div id="main">
<p>
<strong>Legend</strong>:
<br />(+) Added feature
<br />(!) Security bug fixed
<br />(-) Bug fixed
<br />(*) Improved/changed feature
<br />( ) Non-code change
</p>
<p>
&nbsp;
</p>
<p>
<strong>Version 2.2.4</strong> (2007-Nov-09)
<br />(!) Fixed DOS bug
<br />( ) Added Vista icon set
</p>
<p>
<strong>Version 2.2.3</strong> (2007-Nov-05)
<br />(!) Fixed XSS bug
</p>
<p>
<strong>Version 2.2.2</strong> (2007-Jul-24)
<br />(!) Fixed XSS bug in search feature
</p>
<p>
<strong>Version 2.2.1</strong> (2007-Jan-06)
<br />(*) Improved handling of passwords with .htaccess
<br />(*) Improved default stylesheet
<br />( ) Added Danish translation
<br />( ) Updated Dutch translation
</p>
<p>
<strong>Version 2.2.0</strong> (2006-Jan-02)
<br />(+) Added a pagination feature
<br />(+) Language is selected based on the user's browser's default
<br />(+) Added support for PHP 5.1.x and higher
<br />( ) Added Greek and Japanese translations
</p>
<p>
<strong>Version 2.1.2</strong> (2005-Aug-11)
<br />(-) Fixed bug when editing descriptions of filenames that have special characters
<br />( ) Added Czech and Slovak translations
</p>
<p>
<strong>Version 2.1.1</strong> (2005-Jul-06)
<br />(!) Fixed bug with search box
<br />( ) Added Swedish translation
</p>
<p>
<strong>Version 2.1.0</strong> (2005-Feb-14)
<br />(+) Added a .htaccess parser
<br />(+) Added an FTP browser
<br />(+) Added <em>moderator</em> and <em>banned</em> account levels
<br />(+) Added a feature to let moderators/admins change their own password
</p>
<p>
<strong>Version 2.0.7</strong> (2005-Jan-14)
<br />(-) Fixed <em>file_description</em> feature
</p>
<p>
<strong>Version 2.0.6</strong> (2005-Jan-04)
<br />(+) Admins are able to copy files from other servers (similar to &quot;wget&quot;)
<br />( ) Added Thai and Arabic translations
</p>
<p>
<strong>Version 2.0.5</strong> (2004-Sep-02)
<br />(+) When <em>force_download</em> is on, the MIME-type sent depends on the file extension
<br />(*) Using <em>hidden_files</em> to only show certain files no longer restricts directories
</p>
<p>
<strong>Version 2.0.4</strong> (2004-Aug-17)
<br />(*) When reconfiguring the script, the current settings are selected instead of the defaults
<br />( ) Added Polish translation
</p>
<p>
<strong>Version 2.0.3</strong> (2004-Jul-26)
<br />(*) Nested if-statements can be used in the template files
<br />(*) Folders do not have to be empty to be deleted
</p>
<p>
<strong>Version 2.0.2</strong> (2004-Jul-13)
<br />(*) All output is XHTML 1.1 compliant
<br />(*) The <em>do_every</em> template command now does not include the last file listed
</p>
<p>
<strong>Version 2.0.1</strong> (2004-Jul-05)
<br />(+) Added directory cache feature
<br />(*) Added <em>include</em> command to the template system
<br />(-) Fixed search page bug when <em>download_count</em> was on
</p>
<p>
<strong>Version 2.0.0</strong> (2004-Jun-24)
</p>
<p>
Complete rewrite from version 1.0:
</p>
<ul>
<li>
Now uses PHP 5. PHP version 5.0 or higher is required.
</li>
<li>
All the features of version 1, plus:
<br />(+) Has a template system for all HTML output
<br />(+) Tar archives of directories can be downloaded
<br />(+) Each user account can have its own home directory
<br />(*) Passwords are stored as a sha-1 hash rather than md5 (this is slightly more secure)
</li>
</ul>
</div>
</body>
</html>

233
classes/Accounts.php Executable file
View File

@@ -0,0 +1,233 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Stores a list of valid user accounts which are read from the user_list file.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.2 (July 21, 2004)
* @package AutoIndex
*/
class Accounts implements Iterator
{
/**
* @var array The list of valid accounts taken from the stored file
*/
private $userlist;
/**
* @var int The size of the $userlist array
*/
private $list_count;
//begin implementation of Iterator
/**
* @var int $i is used to keep track of the current pointer inside the array when implementing Iterator
*/
private $i;
/**
* @return User The current element in the array
*/
public function current()
{
if ($this -> i < $this -> list_count)
{
return $this -> userlist[$this -> i];
}
return false;
}
/**
* Increments the internal array pointer, then returns the user at that
* new position.
*
* @return User The current position of the pointer in the array
*/
public function next()
{
$this -> i++;
return $this -> current();
}
/**
* Sets the internal array pointer to 0.
*/
public function rewind()
{
$this -> i = 0;
}
/**
* @return bool True if $i is a valid array index
*/
public function valid()
{
return ($this -> i < $this -> list_count);
}
/**
* @return int Returns $i, the key of the array
*/
public function key()
{
return $this -> i;
}
//end implementation of Iterator
/**
* Reads the user_list file, and fills the $contents array with the
* valid users.
*/
public function __construct()
{
global $config;
$file = @file($config -> __get('user_list'));
if ($file === false)
{
throw new ExceptionDisplay('Cannot open user account file.');
}
$this -> userlist = array();
foreach ($file as $line_num => $line)
{
$line = rtrim($line, "\r\n");
if (ConfigData::line_is_comment($line))
{
continue;
}
$parts = explode("\t", $line);
if (count($parts) !== 4)
{
throw new ExceptionDisplay('Incorrect format for user accounts file on line '
. ($line_num + 1));
}
$this -> userlist[] = new User($parts[0], $parts[1], $parts[2], $parts[3]);
}
$this -> list_count = count($this -> userlist);
$this -> i = 0;
}
/**
* @param string $name Username to find the level of
* @return int The level of the user
*/
public function get_level($name)
{
foreach ($this as $look)
{
if (strcasecmp($look -> username, $name) !== 0)
{
continue;
}
$lev = (int)$look -> level;
if ($lev < BANNED || $lev > ADMIN)
{
throw new ExceptionDisplay('Invalid level for user <em>'
. Url::html_output($name) . '</em>.');
}
return $lev;
}
throw new ExceptionDisplay('User <em>' . Url::html_output($name)
. '</em> does not exist.');
}
/**
* @param string $name Username to find the home directory for
* @return string The home directory of $name
*/
public function get_home_dir($name)
{
foreach ($this as $look)
{
if (strcasecmp($look -> username, $name) === 0)
{
return $look -> home_dir;
}
}
throw new ExceptionDisplay('User <em>' . Url::html_output($name)
. '</em> does not exist.');
}
/**
* Returns $name with the character case the same as it is in the accounts
* file.
*
* @param string $name Username to find the stored case of
* @return string
*/
public function get_stored_case($name)
{
foreach ($this as $look)
{
if (strcasecmp($look -> username, $name) === 0)
{
return $look -> username;
}
}
throw new ExceptionDisplay('User <em>' . Url::html_output($name)
. '</em> does not exist.');
}
/**
* @param User $user The user to determine if it is valid or not
* @return bool True if the username and password are correct
*/
public function is_valid_user(User $user)
{
foreach ($this as $look)
{
if ($look -> equals($user))
{
return true;
}
}
return false;
}
/**
* @param string $name Username to find if it exists or not
* @return bool True if a user exists with the username $name
*/
public function user_exists($name)
{
foreach ($this as $look)
{
if (strcasecmp($look -> username, $name) === 0)
{
return true;
}
}
return false;
}
}
?>

990
classes/Admin.php Executable file
View File

@@ -0,0 +1,990 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2005 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Lets admins move/rename/delete files and implements the other actions in the
* admin panel.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.1.1 (August 10, 2005)
* @package AutoIndex
*/
class Admin
{
/**
* @var int The level of the logged in user
*/
private $level;
/**
* @var string The name of the logged in user
*/
private $username;
/**
* @param string $path The path of the directory to create
* @return bool True on success, false on failure
*/
public static function mkdir_recursive($path)
{
$path = Item::make_sure_slash($path);
if (@is_dir($path))
{
return true;
}
if (!self::mkdir_recursive(dirname($path)))
{
return false;
}
return @mkdir($path, 0755);
}
/**
* Deletes a directory and all its contents.
*
* @param string $path The path of the directory to delete
* @return bool True on success, false on failure
*/
private static function rmdir_recursive($path)
{
$path = Item::make_sure_slash($path);
$list = @scandir($path);
if ($list === false)
{
return false;
}
foreach ($list as $file)
{
if ($file == '' || $file == '.' || $file == '..')
{
continue;
}
$dir = "$path$file/";
@is_dir($dir) ? self::rmdir_recursive($dir) : @unlink($dir);
}
return @rmdir($path);
}
/**
* Copies a remote file to the local server.
*
* @param string $protocol Either ftp:// or http://
* @param string $url The rest of the URL after the protocol
*/
private static function copy_remote_file($protocol, $url)
{
if ($protocol == '' || $url == '')
{
throw new ExceptionDisplay('Please go back and enter a file to copy.');
}
global $dir;
$local_file = $dir . Item::get_basename($url);
if (@file_exists($local_file))
{
throw new ExceptionDisplay('The file already exists in this directory.');
}
$remote = $protocol . $url;
$r = @fopen($remote, 'rb');
if ($r === false)
{
throw new ExceptionDisplay('Cannot open remote file for reading: <em>'
. Url::html_output($remote) . '</em>');
}
$l = @fopen($local_file, 'wb');
if ($l === false)
{
throw new ExceptionDisplay('Cannot open local file for writing.');
}
while (true)
{
$temp = fread($r, 8192);
if ($temp === '')
{
break;
}
fwrite($l, $temp);
}
fclose($l);
fclose($r);
}
/**
* @param string $filename The path to the file that stores the info
* @param string $old_name The old name of the file or folder to update inside of $filename
* @param string $new_name The new name of the file or folder
*/
private static function update_file_info($filename, $old_name, $new_name)
{
if (!@is_file($filename))
{
throw new ExceptionDisplay('The file <em>'
. Url::html_output($filename) . '</em> does not exist.');
}
$text = @file_get_contents($filename);
if ($text === false)
{
throw new ExceptionDisplay('Cannot open file <em>'
. Url::html_output($filename) . '</em> for reading.');
}
$h = @fopen($filename, 'wb');
if ($h === false)
{
throw new ExceptionDisplay('Cannot open file <em>'
. Url::html_output($filename) . '</em> for writing.');
}
fwrite($h, preg_replace('/^' . preg_quote($old_name, '/')
. '/m', $new_name, $text));
fclose($h);
}
/**
* Validates a potential new password.
*
* @param string $pass1 The new password
* @param string $pass2 The new password typed again
*/
private static function validate_new_password($pass1, $pass2)
{
if ($pass1 != $pass2)
{
throw new ExceptionDisplay('Passwords do not match.');
}
if (strlen($pass1) < 6)
{
throw new ExceptionDisplay('Password must be at least 6 characters long.');
}
}
/**
* Changes a user's password.
*
* @param string $username The username
* @param string $old_pass The user's old password
* @param string $new_pass1 The new password
* @param string $new_pass2 The new password typed again
*/
private static function change_password($username, $old_pass, $new_pass1, $new_pass2)
{
self::validate_new_password($new_pass1, $new_pass2);
$accounts = new Accounts();
if (!$accounts -> user_exists($username))
{
throw new ExceptionDisplay('Cannot change password: username does not exist.');
}
if (!$accounts -> is_valid_user(new User($username, sha1($old_pass))))
{
throw new ExceptionDisplay('Incorrect old password.');
}
global $config;
$h = @fopen($config -> __get('user_list'), 'wb');
if ($h === false)
{
throw new ExceptionDisplay("Could not open file <em>$user_list</em> for writing."
. ' Make sure PHP has write permission to this file.');
}
foreach ($accounts as $this_user)
{
if (strcasecmp($this_user -> username, $username) === 0)
{
$this_user = new User($username, sha1($new_pass1), $this_user -> level, $this_user -> home_dir);
}
fwrite($h, $this_user -> __toString());
}
fclose($h);
$_SESSION['password'] = sha1($new_pass1);
throw new ExceptionDisplay('Password successfully changed.');
}
/**
* Changes a user's level.
*
* @param string $username The username
* @param int $new_level The user's new level
*/
private static function change_user_level($username, $new_level)
{
if ($new_level < BANNED || $new_level > ADMIN)
{
throw new ExceptionDisplay('Invalid user level.');
}
$accounts = new Accounts();
if (!$accounts -> user_exists($username))
{
throw new ExceptionDisplay('Cannot change level: username does not exist.');
}
global $config;
$h = @fopen($config -> __get('user_list'), 'wb');
if ($h === false)
{
throw new ExceptionDisplay("Could not open file <em>$user_list</em> for writing."
. ' Make sure PHP has write permission to this file.');
}
foreach ($accounts as $this_user)
{
if (strcasecmp($this_user -> username, $username) === 0)
{
$this_user = new User($username, $this_user -> sha1_pass, $new_level, $this_user -> home_dir);
}
fwrite($h, $this_user -> __toString());
}
fclose($h);
throw new ExceptionDisplay('User level successfully changed.');
}
/**
* @param string $username The name of the new user to create
* @param string $pass1 The raw password
* @param string $pass2 The raw password repeated again for verification
* @param int $level The level of the user (use GUEST USER ADMIN constants)
* @param string $home_dir The home directory of the user, or blank for the default
*/
private static function add_user($username, $pass1, $pass2, $level, $home_dir = '')
{
self::validate_new_password($pass1, $pass2);
$username_reg_exp = '/^[A-Za-z0-9_-]+$/';
if (!preg_match($username_reg_exp, $username))
{
throw new ExceptionDisplay('The username must only contain alpha-numeric characters, underscores, or dashes.'
. '<br /><span class="autoindex_small">It must match the regular expression: <strong>'
. Url::html_output($username_reg_exp) . '</strong></span>');
}
if ($home_dir != '')
{
$home_dir = Item::make_sure_slash($home_dir);
if (!@is_dir($home_dir))
{
throw new ExceptionDisplay('The user\'s home directory is not valid directory.');
}
}
$list = new Accounts();
if ($list -> user_exists($username))
{
throw new ExceptionDisplay('This username already exists.');
}
global $config;
$h = @fopen($config -> __get('user_list'), 'ab');
if ($h === false)
{
throw new ExceptionDisplay('User list file could not be opened for writing.');
}
$new_user = new User($username, sha1($pass1), $level, $home_dir);
fwrite($h, $new_user -> __toString());
fclose($h);
throw new ExceptionDisplay('User successfully added.');
}
/**
* @param string $username Deletes user with the name $username
*/
private static function del_user($username)
{
$accounts = new Accounts();
if (!$accounts -> user_exists($username))
{
throw new ExceptionDisplay('Cannot delete user: username does not exist.');
}
global $config;
$h = @fopen($config -> __get('user_list'), 'wb');
if ($h === false)
{
throw new ExceptionDisplay("Could not open file <em>$user_list</em> for writing."
. ' Make sure PHP has write permission to this file.');
}
foreach ($accounts as $this_user)
{
if (strcasecmp($this_user -> username, $username) !== 0)
{
fwrite($h, $this_user -> __toString());
}
}
fclose($h);
throw new ExceptionDisplay('User successfully removed.');
}
/**
* @param User $current_user This user is checked to make sure it really is an admin
*/
public function __construct(User $current_user)
{
if (!($current_user instanceof UserLoggedIn))
{
throw new ExceptionDisplay('You must be logged in to access this section.');
}
$this -> level = $current_user -> level;
$this -> username = $current_user -> username;
}
/**
* @param string $action
*/
public function action($action)
{
//This is a list of the actions moderators can do (otherwise, the user must be an admin)
$mod_actions = array('edit_description', 'change_password', 'ftp');
if (in_array(strtolower($action), $mod_actions))
{
if ($this -> level < MODERATOR)
{
throw new ExceptionDisplay('You must be a moderator to access this section.');
}
}
else if ($this -> level < ADMIN)
{
throw new ExceptionDisplay('You must be an administrator to access this section.');
}
switch (strtolower($action))
{
case 'config':
{
/** Include the config generator file. */
if (!@include_once(CONFIG_GENERATOR))
{
throw new ExceptionDisplay('Error including file <em>'
. CONFIG_GENERATOR . '</em>');
}
die();
}
case 'rename':
{
if (!isset($_GET['filename']))
{
throw new ExceptionDisplay('No filenames specified.');
}
global $dir;
$old = $dir . Url::clean_input($_GET['filename']);
if (!@file_exists($old))
{
header('HTTP/1.0 404 Not Found');
throw new ExceptionDisplay('Specified file could not be found.');
}
if (isset($_GET['new_name']))
{
$new = $dir . Url::clean_input($_GET['new_name']);
if ($old == $new)
{
throw new ExceptionDisplay('Filename unchanged.');
}
if (@file_exists($new))
{
throw new ExceptionDisplay('Cannot overwrite existing file.');
}
if (@rename($old, $new))
{
global $config;
if (DOWNLOAD_COUNT)
{
self::update_file_info($config -> __get('download_count'), $old, $new);
}
if (DESCRIPTION_FILE)
{
self::update_file_info($config -> __get('description_file'), $old, $new);
}
throw new ExceptionDisplay('File renamed successfully.');
}
throw new ExceptionDisplay('Error renaming file.');
}
global $words, $subdir;
throw new ExceptionDisplay('<p>' . $words -> __get('renaming')
. ' <em>' . Url::html_output($_GET['filename'])
. '</em></p><p>' . $words -> __get('new filename')
. ':<br /><span class="autoindex_small">('
. $words -> __get('you can also move the file by specifying a path')
. ')</span></p><form method="get" action="' . Url::html_output($_SERVER['PHP_SELF'])
. '"><p><input type="hidden" name="filename" value="'
. $_GET['filename'] . '" />'
. '<input type="hidden" name="dir" value="' . $subdir
. '" /><input type="hidden" name="action" value="rename" />'
. '<input type="text" name="new_name" size="40" value="'
. $_GET['filename'] . '" />'
. '<input type="submit" value="' . $words -> __get('rename')
. '" /></p></form>');
}
case 'delete':
{
if (!isset($_GET['filename']))
{
throw new ExceptionDisplay('No filename specified.');
}
if (isset($_GET['sure']))
{
global $dir;
$to_delete = $dir . Url::clean_input($_GET['filename']);
if (!@file_exists($to_delete))
{
header('HTTP/1.0 404 Not Found');
throw new ExceptionDisplay('Specified file could not be found.');
}
if (@is_dir($to_delete))
{
if (self::rmdir_recursive($to_delete))
{
throw new ExceptionDisplay('Folder successfully deleted.');
}
throw new ExceptionDisplay('Error deleting folder.');
}
if (@unlink($to_delete))
{
throw new ExceptionDisplay('File successfully deleted.');
}
throw new ExceptionDisplay('Error deleting file.');
}
global $words, $subdir;
throw new ExceptionDisplay('<p>'
. $words -> __get('are you sure you want to delete the file')
. ' <em>' . Url::html_output($_GET['filename']) . '</em>?</p>'
. '<form method="get" action="' . Url::html_output($_SERVER['PHP_SELF'])
. '"><p><input type="hidden" name="action" value="delete" />'
. '<input type="hidden" name="dir" value="' . $subdir
. '" /><input type="hidden" name="sure" value="true" />'
. '<input type="hidden" name="filename" value="'
. $_GET['filename'] . '" /><input type="submit" value="'
. $words -> __get('yes, delete') . '" /></p></form>');
}
case 'add_user':
{
if (isset($_POST['username'], $_POST['pass1'], $_POST['pass2'], $_POST['level'], $_POST['home_dir']))
{
self::add_user($_POST['username'], $_POST['pass1'],
$_POST['pass2'], (int)$_POST['level'], $_POST['home_dir']);
}
global $words;
throw new ExceptionDisplay($words -> __get('add user')
. ':<form method="post" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '?action=add_user"><p>'
. $words -> __get('username') . ': <input type="text" name="username" /><br />'
. $words -> __get('password') . ': <input type="password" name="pass1" /><br />'
. $words -> __get('password') . ': <input type="password" name="pass2" /><br />'
. $words -> __get('level') . ': <select name="level"><option value="' . GUEST . '">'
. $words -> __get('guest') . '</option><option selected="selected" value="' . USER . '">'
. $words -> __get('user') . '</option><option value="' . MODERATOR . '">'
. $words -> __get('mod') . '</option><option value="' . ADMIN . '">'
. $words -> __get('admin') . '</option></select></p><p>Home Directory: '
. '<input type="text" name="home_dir" /><br /><span class="autoindex_small">(leave blank to use the default base directory)</span></p><p><input type="submit" value="'
. $words -> __get('add user') . '" /></p></form>');
}
case 'change_password':
{
if (isset($_POST['pass1'], $_POST['pass2'], $_POST['old_pass']))
{
self::change_password($this -> username, $_POST['old_pass'],
$_POST['pass1'], $_POST['pass2']);
}
throw new ExceptionDisplay('<form method="post" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '?action=change_password">
<p>Old password: <input type="password" name="old_pass" />
<br />New password: <input type="password" name="pass1" />
<br />New password: <input type="password" name="pass2" /></p>
<p><input type="submit" value="Change" /></p></form>');
}
case 'change_user_level':
{
if (isset($_POST['username'], $_POST['level']))
{
self::change_user_level($_POST['username'], (int)$_POST['level']);
}
$accounts = new Accounts();
$out = '<form method="post" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '?action=change_user_level">
<p>Select user: <select name="username">';
foreach ($accounts as $this_user)
{
$out .= '<option>' . $this_user -> username . '</option>';
}
global $words;
throw new ExceptionDisplay($out
. '</select></p><p>Select new level: <select name="level"><option value="' . BANNED . '">
Banned</option><option value="' . GUEST . '">'
. $words -> __get('guest') . '</option><option selected="selected" value="' . USER . '">'
. $words -> __get('user') . '</option><option value="' . MODERATOR . '">'
. $words -> __get('mod') . '</option><option value="' . ADMIN . '">'
. $words -> __get('admin') . '</option></select></p>
<p><input type="submit" value="Change user\'s level" /></p></form>');
}
case 'del_user':
{
if (isset($_POST['username']))
{
if (isset($_POST['sure']))
{
self::del_user($_POST['username']);
}
global $words;
throw new ExceptionDisplay('<p>'
. $words -> __get('are you sure you want to remove the user')
. ' <em>'.$_POST['username'] . '</em>?</p>'
. '<form method="post" action="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=del_user">'
. '<p><input type="hidden" name="sure" value="true" /><input type="hidden" name="username" value="'
. $_POST['username'] . '" /><input type="submit" value="'
. $words -> __get('yes, delete') . '" /></p></form>');
}
global $words;
$accounts = new Accounts();
$out = '<p>' . $words -> __get('select user to remove')
. ':</p><form method="post" action="' . Url::html_output($_SERVER['PHP_SELF'])
. '?action=del_user"><p><select name="username">';
foreach ($accounts as $this_user)
{
$out .= '<option>' . $this_user -> username . '</option>';
}
throw new ExceptionDisplay($out
. '</select></p><p><input type="submit" value="'
. $words -> __get('delete this user') . '" /></p></form>');
}
case 'edit_description':
{
if (isset($_GET['filename']))
{
global $dir;
$filename = $dir . $_GET['filename'];
if (isset($_GET['description']))
{
global $descriptions, $config;
if (DESCRIPTION_FILE && $descriptions -> is_set($filename))
//if it's already set, update the old description
{
//update the new description on disk
$h = @fopen($config -> __get('description_file'), 'wb');
if ($h === false)
{
throw new ExceptionDisplay('Could not open description file for writing.'
. ' Make sure PHP has write permission to this file.');
}
foreach ($descriptions as $file => $info)
{
fwrite($h, "$file\t" . (($file == $filename) ? $_GET['description'] : $info) . "\n");
}
fclose($h);
//update the new description in memory
$descriptions -> set($filename, $_GET['description']);
}
else if ($_GET['description'] != '')
//if it's not set, add it to the end
{
$h = @fopen($config -> __get('description_file'), 'ab');
if ($h === false)
{
throw new ExceptionDisplay('Could not open description file for writing.'
. ' Make sure PHP has write permission to this file.');
}
fwrite($h, "$filename\t" . $_GET['description'] . "\n");
fclose($h);
//read the description file with the updated data
$descriptions = new ConfigData($config -> __get('description_file'));
}
}
else
{
global $words, $subdir, $descriptions;
$current_desc = (DESCRIPTION_FILE && $descriptions -> is_set($filename) ? $descriptions -> __get($filename) : '');
throw new ExceptionDisplay('<p>'
. $words -> __get('enter the new description for the file')
. ' <em>' . Url::html_output($_GET['filename'])
. '</em>:</p><form method="get" action="' . Url::html_output($_SERVER['PHP_SELF'])
. '"><p><input type="hidden" name="dir" value="'
. $subdir . '" /><input type="hidden" name="filename" value="'
. $_GET['filename'] . '" />'
. '<input type="hidden" name="action" value="edit_description" /></p><p><input type="text" name="description" size="50" value="'
. Url::html_output($current_desc)
. '" /></p><p><input class="button" type="submit" value="'
. $words -> __get('change') . '" /></p></form>');
}
}
else
{
throw new ExceptionDisplay('No filename specified.');
}
break;
}
case 'edit_hidden':
{
if (!HIDDEN_FILES)
{
throw new ExceptionDisplay('The file hiding system is not in use. To enable it, reconfigure the script.');
}
global $hidden_list;
if (isset($_GET['add']) && $_GET['add'] != '')
{
global $config;
$h = @fopen($config -> __get('hidden_files'), 'ab');
if ($h === false)
{
throw new ExceptionDisplay('Unable to open hidden files list for writing.');
}
fwrite($h, $_GET['add'] . "\n");
fclose($h);
throw new ExceptionDisplay('Hidden file added.');
}
if (isset($_GET['remove']))
{
global $config;
$h = @fopen($config -> __get('hidden_files'), 'wb');
if ($h === false)
{
throw new ExceptionDisplay('Unable to open hidden files list for writing.');
}
foreach ($hidden_list as $hid)
{
if ($hid != $_GET['remove'])
{
fwrite($h, $hid . "\n");
}
}
fclose($h);
throw new ExceptionDisplay('Hidden file removed.');
}
global $words;
$str = '<h4>' . $words -> __get('add a new hidden file') . ':</h4>'
. '<p class="autoindex_small">You can also use wildcards (?, *, +) for each entry.<br />'
. 'If you want to do the opposite of "hidden files" - show only certain files - '
. 'put a colon in front of those entries.</p><form method="get" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '"><p><input type="hidden" name="action" value="edit_hidden" />'
. '<input type="text" name="add" size="40" /> <input type="submit" value="'
. $words -> __get('add') . '" /></p></form>';
$str .= '<hr class="autoindex_hr" /><h4>' . $words -> __get('remove a hidden file')
. ':</h4><form method="get" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '"><p><select name="remove">';
foreach ($hidden_list as $hid)
{
$str .= '<option>' . Url::html_output($hid) . '</option>';
}
$str .= '</select><input type="hidden" name="action" value="edit_hidden" /> <input type="submit" value="'
. $words -> __get('remove') . '" /></p></form>';
throw new ExceptionDisplay($str);
}
case 'edit_banned':
{
if (!BANNED_LIST)
{
throw new ExceptionDisplay('The banning system is not in use. To enable it, reconfigure the script.');
}
if (isset($_GET['add']) && $_GET['add'] != '')
{
global $config;
$h = @fopen($config -> __get('banned_list'), 'ab');
if ($h === false)
{
throw new ExceptionDisplay('Unable to open banned_list for writing.');
}
fwrite($h, $_GET['add'] . "\n");
fclose($h);
throw new ExceptionDisplay('Ban added.');
}
if (isset($_GET['remove']))
{
global $b_list, $config;
$h = @fopen($config -> __get('banned_list'), 'wb');
if ($h === false)
{
throw new ExceptionDisplay('Unable to open banned_list for writing.');
}
foreach ($b_list as $ban)
{
if ($ban != $_GET['remove'])
{
fwrite($h, $ban . "\n");
}
}
fclose($h);
throw new ExceptionDisplay('Ban removed.');
}
global $b_list, $words;
$str = '<h4>' . $words -> __get('add a new ban') . ':</h4><form method="get" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '"><p><input type="hidden" name="action" value="edit_banned" />'
. '<input type="text" name="add" size="40" /> <input type="submit" value="'
. $words -> __get('add') . '" /></p></form>';
$str .= '<hr class="autoindex_hr" /><h4>'
. $words -> __get('remove a ban') . ':</h4><form method="get" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '"><p><select name="remove">';
foreach ($b_list as $ban)
{
$str .= '<option>' . $ban . '</option>';
}
$str .= '</select><input type="hidden" name="action" value="edit_banned" /> <input type="submit" value="'
. $words -> __get('remove') . '" /></p></form>';
throw new ExceptionDisplay($str);
}
case 'stats':
{
if (!LOG_FILE)
{
throw new ExceptionDisplay('The logging system has not been enabled.');
}
$stats = new Stats();
$stats -> display();
break;
}
case 'view_log':
{
if (!LOG_FILE)
{
throw new ExceptionDisplay('The logging system has not been enabled.');
}
global $log;
if (isset($_GET['num']))
{
$log -> display((int)$_GET['num']);
}
global $words;
throw new ExceptionDisplay($words -> __get('how many entries would you like to view')
. '?<form method="get" action="' . Url::html_output($_SERVER['PHP_SELF'])
. '"><input type="hidden" name="action" value="view_log" />'
. '<input name="num" size="3" type="text" /> <input type="submit" value="'
. $words -> __get('view') . '" /></form>');
}
case 'create_dir':
{
if (isset($_GET['name']))
{
global $dir;
if (!self::mkdir_recursive($dir . $_GET['name']))
{
throw new ExceptionDisplay('Error creating new folder.');
}
}
else
{
global $words, $subdir;
throw new ExceptionDisplay('<p>' . $words -> __get('enter the new name')
. ':</p><form method="get" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '"><p><input type="hidden" name="action" value="create_dir" />'
. '<input name="name" size="25" type="text" /> <input type="submit" value="'
. $words -> __get('create') . '" /><input type="hidden" name="dir" value="'
. $subdir . '" /></p></form>');
}
break;
}
case 'copy_url':
{
if (isset($_GET['protocol'], $_GET['copy_file']))
{
self::copy_remote_file(rawurldecode($_GET['protocol']), rawurldecode($_GET['copy_file']));
throw new ExceptionDisplay('Copy was successful.');
}
global $dir;
$text = '
<table border="0" cellpadding="8" cellspacing="0">
<tr class="paragraph"><td class="autoindex_td" style="padding: 8px;">
<p>Enter the name of the remote file you would like to copy:</p>
<form method="get" action="' . Url::html_output($_SERVER['PHP_SELF']) . '">
<p><input type="hidden" name="action" value="copy_url" />
<input type="hidden" name="dir" value="' . $dir . '" />
<input type="radio" name="protocol" value="http://" checked="checked" />http://
<br /><input type="radio" name="protocol" value="ftp://" />ftp://
<input type="text" name="copy_file" /></p>
<p><input class="button" type="submit" value="Copy" />
</p></form></td></tr></table>';
echo new Display($text);
die();
}
case 'ftp':
{
if (isset($_POST['host'], $_POST['port'], $_POST['directory'],
$_POST['ftp_username'], $_POST['ftp_password']))
{
if ($_POST['host'] == '')
{
throw new ExceptionDisplay('Please go back and enter a hostname.');
}
if ($_POST['ftp_username'] == '' && $_POST['ftp_password'] == '')
//anonymous login
{
$_POST['ftp_username'] = 'anonymous';
$_POST['ftp_password'] = 'autoindex@sourceforge.net';
}
if ($_POST['directory'] == '')
{
$_POST['directory'] = './';
}
if ($_POST['port'] == '')
{
$_POST['port'] = 21;
}
$_SESSION['ftp'] = array(
'host' => $_POST['host'],
'port' => (int)$_POST['port'],
'directory' => Item::make_sure_slash($_POST['directory']),
'username' => $_POST['ftp_username'],
'password' => $_POST['ftp_password'],
'passive' => isset($_POST['passive'])
);
}
if (isset($_GET['set_dir']))
{
$_SESSION['ftp']['directory'] = $_GET['set_dir'];
}
global $subdir;
if (isset($_GET['ftp_logout']))
{
unset($_SESSION['ftp']);
$text = '<p>Logout successful. <a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']) . '?dir='
. rawurlencode($subdir) . '">Go back.</a></p>';
}
else if (isset($_SESSION['ftp']))
{
try
{
$ftp = new Ftp($_SESSION['ftp']['host'], $_SESSION['ftp']['port'],
$_SESSION['ftp']['passive'], $_SESSION['ftp']['directory'],
$_SESSION['ftp']['username'], $_SESSION['ftp']['password']);
}
catch (ExceptionFatal $e)
{
unset($_SESSION['ftp']);
throw $e;
}
if (isset($_GET['filename']) && $_GET['filename'] != '')
//transfer local to FTP
{
global $dir;
$name = rawurldecode($_GET['filename']);
$ftp -> put_file($dir . $name, Item::get_basename($name));
throw new ExceptionDisplay('File successfully transferred to FTP server.');
}
if (isset($_GET['transfer']) && $_GET['transfer'] != '')
//transfer FTP to local
{
global $dir;
$name = rawurldecode($_GET['transfer']);
$ftp -> get_file($dir . Item::get_basename($name), $name);
throw new ExceptionDisplay('File successfully transferred from FTP server.');
}
global $words;
$text = '<ul><li><a href="' . Url::html_output($_SERVER['PHP_SELF'])
. '?action=ftp&amp;dir=' . rawurlencode($subdir) . '&amp;set_dir='
. rawurlencode(DirItem::get_parent_dir($_SESSION['ftp']['directory']))
. '">../ (' . $words -> __get('parent directory') . ')</a></li>';
$i = 0;
foreach ($ftp as $file)
{
$is_directory = $ftp -> is_directory($i++);
$command = ($is_directory ? 'set_dir' : 'transfer');
$slash = ($is_directory ? '/' : '');
$text .= '<li><a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']) . '?action=ftp&amp;'
. $command . '=' . rawurlencode($file)
. '&amp;dir=' . rawurlencode($subdir) . '">'
. $file . $slash . '</a></li>' . "\n";
}
$text .= '</ul><p><a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']) . '?action=ftp&amp;dir='
. rawurlencode($subdir) . '&amp;ftp_logout=true">Logout of FTP server</a>
<br /><a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?dir='
. rawurlencode($subdir) . '">Back to index.</a></p>';
}
else
{
$text = '<form method="post" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '?action=ftp&amp;dir='
. rawurlencode($subdir) . '"><table border="0" cellpadding="8" cellspacing="0">
<tr class="paragraph"><td class="autoindex_td" style="padding: 8px;">
<p>FTP server: <input type="text" name="host" />
port <input type="text" size="3" name="port" value="21" />
<br /><input type="checkbox" name="passive" value="true" />Passive Mode</p>
<p>Username: <input type="text" name="ftp_username" />
<br />Password: <input type="password" name="ftp_password" />
<span class="autoindex_small">(Leave these blank to login anonymously)</span>
</p><p>Directory: <input type="text" name="directory" value="./" />
</p><p><input type="submit" value="Connect" /></p></td></tr></table></form>
<p><a class="autoindex_a" href="' . Url::html_output($_SERVER['PHP_SELF'])
. '?dir=' . rawurlencode($subdir) . '">Back to index.</a></p>';
}
echo new Display($text);
die();
}
default:
{
throw new ExceptionDisplay('Invalid admin action.');
}
}
}
/**
* @return string The HTML text that makes up the admin panel
*/
public function __toString()
{
global $words, $subdir;
$str = '';
//only ADMIN accounts
if ($this -> level >= ADMIN) $str = '
<p>
<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=config" class="autoindex_a">'
. $words -> __get('reconfigure script') . '</a>
</p>
<p>
<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=edit_hidden" class="autoindex_a">'
. $words -> __get('edit list of hidden files') . '</a>
<br /><a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=edit_banned" class="autoindex_a">'
. $words -> __get('edit ban list') . '</a>
</p>
<p>
<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=create_dir&amp;dir=' . rawurlencode($subdir)
. '" class="autoindex_a">' . $words -> __get('create new directory in this folder')
. '</a><br /><a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=copy_url&amp;dir='
. $subdir . '" class="autoindex_a">' . $words -> __get('copy url') . '</a>
</p>
<p>
<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=view_log" class="autoindex_a">'
. $words -> __get('view entries from log file') . '</a>
<br /><a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=stats" class="autoindex_a">'
. $words -> __get('view statistics from log file') . '</a>
</p>
<p>
<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=add_user" class="autoindex_a">'
. $words -> __get('add new user') . '</a>
<br /><a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=del_user" class="autoindex_a">'
. $words -> __get('delete user') . '</a>
<br /><a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=change_user_level" class="autoindex_a">
Change a user\'s level</a>
</p>';
//MODERATOR and ADMIN accounts
if ($this -> level >= MODERATOR) $str .= '
<p>
<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=change_password" class="autoindex_a">
Change your password</a>
</p>
<p>
<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=ftp&amp;dir=' . rawurlencode($subdir)
. '" class="autoindex_a">FTP browser</a>
</p>';
return $str;
}
}
?>

233
classes/ConfigData.php Executable file
View File

@@ -0,0 +1,233 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2005 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Reads information stored in files, where the key and data are separated by a
* tab.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.2 (January 13, 2005)
* @package AutoIndex
*/
class ConfigData implements Iterator
{
/**
* @var array A list of all the settings
*/
private $config;
/**
* @var string The name of the file to read the settings from
*/
private $filename;
//begin implementation of Iterator
/**
* @var bool
*/
private $valid;
/**
* @return string
*/
public function current()
{
return current($this -> config);
}
/**
* Increments the internal array pointer, and returns the new value.
*
* @return string
*/
public function next()
{
$t = next($this -> config);
if ($t === false)
{
$this -> valid = false;
}
return $t;
}
/**
* Sets the internal array pointer to the beginning.
*/
public function rewind()
{
reset($this -> config);
}
/**
* @return bool
*/
public function valid()
{
return $this -> valid;
}
/**
* @return string
*/
public function key()
{
return key($this -> config);
}
//end implementation of Iterator
/**
* @param string $line The line to test
* @return bool True if $line starts with characters that mean it is a comment
*/
public static function line_is_comment($line)
{
$line = trim($line);
return (($line == '') || preg_match('@^(//|<\?|\?>|/\*|\*/|#)@', $line));
}
/**
* @param string $file The filename to read the data from
*/
public function __construct($file)
{
if ($file === false)
{
return;
}
$this -> valid = true;
$this -> filename = $file;
$contents = @file($file);
if ($contents === false)
{
throw new ExceptionFatal('Error reading file <em>'
. Url::html_output($file) . '</em>');
}
foreach ($contents as $i => $line)
{
$line = rtrim($line, "\r\n");
if (self::line_is_comment($line))
{
continue;
}
$parts = explode("\t", $line, 2);
if (count($parts) !== 2 || $parts[0] == '' || $parts[1] == '')
{
throw new ExceptionFatal('Incorrect format for file <em>'
. Url::html_output($file) . '</em> on line ' . ($i + 1)
. '.<br />Format is "variable name[tab]value"');
}
if (isset($this -> config[$parts[0]]))
{
throw new ExceptionFatal('Error in <em>'
. Url::html_output($file) . '</em> on line ' . ($i + 1)
. '.<br />' . Url::html_output($parts[0])
. ' is already defined.');
}
$this -> config[$parts[0]] = $parts[1];
}
}
/**
* $config[$key] will be set to $info.
*
* @param string $key
* @param string $info
*/
public function set($key, $info)
{
$this -> config[$key] = $info;
}
/**
* This will look for the key $item, and add one to the $info (assuming
* it is an integer).
*
* @param string $item The key to look for
*/
public function add_one($item)
{
if ($this -> is_set($item))
{
$h = @fopen($this -> filename, 'wb');
if ($h === false)
{
throw new ExceptionFatal('Could not open file <em>'
. Url::html_output($this -> filename)
. '</em> for writing. Make sure PHP has write permission to this file.');
}
foreach ($this as $current_item => $count)
{
fwrite($h, "$current_item\t"
. (($current_item == $item) ? ((int)$count + 1) : $count)
. "\n");
}
}
else
{
$h = @fopen($this -> filename, 'ab');
if ($h === false)
{
throw new ExceptionFatal('Could not open file <em>'
. $this -> filename . '</em> for writing.'
. ' Make sure PHP has write permission to this file.');
}
fwrite($h, "$item\t1\n");
}
fclose($h);
}
/**
* @param string $name The key to look for
* @return bool True if $name is set
*/
public function is_set($name)
{
return isset($this -> config[$name]);
}
/**
* @param string $name The key to look for
* @return string The value $name points to
*/
public function __get($name)
{
if (isset($this -> config[$name]))
{
return $this -> config[$name];
}
throw new ExceptionFatal('Setting <em>' . Url::html_output($name)
. '</em> is missing in file <em>'
. Url::html_output($this -> filename) . '</em>.');
}
}
?>

167
classes/DirItem.php Executable file
View File

@@ -0,0 +1,167 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Subclass of item that specifically represents a directory.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (June 30, 2004)
* @package AutoIndex
*/
class DirItem extends Item
{
/**
* @var DirectoryList The list of this directory's contents
*/
private $temp_list;
/**
* @return string Always returns 'dir', since this is a directory, not a file
*/
public function file_ext()
{
return 'dir';
}
/**
* @return int The total size in bytes of the folder (recursive)
*/
private function dir_size()
{
if (!isset($this -> temp_list))
{
$this -> temp_list = new DirectoryList($this -> parent_dir . $this -> filename);
}
return $this -> temp_list -> size_recursive();
}
/**
* @return int The total number of files in the folder (recursive)
*/
public function num_subfiles()
{
if (!isset($this -> temp_list))
{
$this -> temp_list = new DirectoryList($this -> parent_dir . $this -> filename);
}
return $this -> temp_list -> num_files();
}
/**
* @param string $path
* @return string The parent directory of $path
*/
public static function get_parent_dir($path)
{
$path = str_replace('\\', '/', $path);
while (preg_match('#/$#', $path))
//remove all slashes from the end
{
$path = substr($path, 0, -1);
}
$pos = strrpos($path, '/');
if ($pos === false)
{
return '';
}
$path = substr($path, 0, $pos + 1);
return (($path === false) ? '' : $path);
}
/**
* @param string $parent_dir
* @param string $filename
*/
public function __construct($parent_dir, $filename)
{
$filename = self::make_sure_slash($filename);
parent::__construct($parent_dir, $filename);
global $config, $subdir;
$this -> downloads = '&nbsp;';
if ($filename == '../')
//link to parent directory
{
if ($subdir != '')
{
global $words;
$this -> is_parent_dir = true;
$this -> filename = $words -> __get('parent directory');
$this -> icon = (ICON_PATH ? $config -> __get('icon_path')
. 'back.png' : '');
$this -> size = new Size(true);
$this -> link = Url::html_output($_SERVER['PHP_SELF']) . '?dir='
. Url::translate_uri(self::get_parent_dir($subdir));
$this -> parent_dir = $this -> new_icon = '';
$this -> a_time = $this -> m_time = false;
}
else
{
$this -> is_parent_dir = $this -> filename = false;
}
}
else
//regular folder
{
if (!@is_dir($this -> parent_dir . $filename))
{
throw new ExceptionDisplay('Directory <em>'
. Url::html_output($this -> parent_dir . $filename)
. '</em> does not exist.');
}
$this -> filename = substr($filename, 0, -1);
$this -> icon = $config -> __get('icon_path') . 'dir.png';
$this -> link = Url::html_output($_SERVER['PHP_SELF']) . '?dir='
. Url::translate_uri(substr($this -> parent_dir, strlen($config -> __get('base_dir'))) . $filename);
}
}
/**
* @param string $var The key to look for
* @return mixed The data stored at the key
*/
public function __get($var)
{
if (isset($this -> $var))
{
return $this -> $var;
}
if ($var == 'size')
{
$this -> size = new Size(SHOW_DIR_SIZE ? $this -> dir_size() : false);
return $this -> size;
}
throw new ExceptionDisplay('Variable <em>' . Url::html_output($var)
. '</em> not set in DirItem class.');
}
}
?>

256
classes/DirectoryList.php Executable file
View File

@@ -0,0 +1,256 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Maintains an array of all files and folders in a directory. Each entry is
* stored as a string (the filename).
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (June 30, 2004)
* @package AutoIndex
*/
class DirectoryList implements Iterator
{
/**
* @var string The directory this object represents
*/
protected $dir_name;
/**
* @var array The list of filesname in this directory (strings)
*/
protected $contents;
/**
* @var int The size of the $contents array
*/
private $list_count;
//begin implementation of Iterator
/**
* @var int $i is used to keep track of the current pointer inside the array when implementing Iterator
*/
private $i;
/**
* @return string The element $i currently points to in the array
*/
public function current()
{
if ($this -> i < count($this -> contents))
{
return $this -> contents[$this -> i];
}
return false;
}
/**
* Increments the internal array pointer, then returns the value
* at that new position.
*
* @return string The current position of the pointer in the array
*/
public function next()
{
$this -> i++;
return $this -> current();
}
/**
* Sets the internal array pointer to 0
*/
public function rewind()
{
$this -> i = 0;
}
/**
* @return bool True if $i is a valid array index
*/
public function valid()
{
return ($this -> i < count($this -> contents));
}
/**
* @return int Returns $i, the key of the array
*/
public function key()
{
return $this -> i;
}
//end implementation of Iterator
/**
* @return int The total size in bytes of the folder (recursive)
*/
public function size_recursive()
{
$total_size = 0;
foreach ($this as $current)
{
$t = $this -> dir_name . $current;
if (@is_dir($t))
{
if ($current != '..')
{
$temp = new DirectoryList($t);
$total_size += $temp -> size_recursive();
}
}
else
{
$total_size += @filesize($t);
}
}
return $total_size;
}
/**
* @return int The total number of files in this directory (recursive)
*/
public function num_files()
{
$count = 0;
foreach ($this as $current)
{
$t = $this -> dir_name . $current;
if (@is_dir($t))
{
if ($current != '..')
{
$temp = new DirectoryList($t);
$count += $temp -> num_files();
}
}
else
{
$count++;
}
}
return $count;
}
/**
* @param string $string The string to search for
* @param array $array The array to search
* @return bool True if $string matches any elements in $array
*/
public static function match_in_array($string, &$array)
{
$string = Item::get_basename($string);
static $replace = array(
'\*' => '[^\/]*',
'\+' => '[^\/]+',
'\?' => '[^\/]?');
foreach ($array as $m)
{
if (preg_match('/^' . strtr(preg_quote(Item::get_basename($m), '/'), $replace) . '$/i', $string))
{
return true;
}
}
return false;
}
/**
* @param string $t The file or folder name
* @param bool $is_file
* @return bool True if $t is listed as a hidden file
*/
public static function is_hidden($t, $is_file = true)
{
$t = Item::get_basename($t);
if ($t == '.' || $t == '')
{
return true;
}
global $you;
if ($you -> level >= ADMIN)
//allow admins to view hidden files
{
return false;
}
global $hidden_files, $show_only_these_files;
if ($is_file && count($show_only_these_files))
{
return (!self::match_in_array($t, $show_only_these_files));
}
return self::match_in_array($t, $hidden_files);
}
/**
* @param string $var The key to look for
* @return mixed The data stored at the key
*/
public function __get($var)
{
if (isset($this -> $var))
{
return $this -> $var;
}
throw new ExceptionDisplay('Variable <em>' . Url::html_output($var)
. '</em> not set in DirectoryList class.');
}
/**
* @param string $path
*/
public function __construct($path)
{
$path = Item::make_sure_slash($path);
if (!@is_dir($path))
{
throw new ExceptionDisplay('Directory <em>' . Url::html_output($path)
. '</em> does not exist.');
}
$temp_list = @scandir($path);
if ($temp_list === false)
{
throw new ExceptionDisplay('Error reading from directory <em>'
. Url::html_output($path) . '</em>.');
}
$this -> dir_name = $path;
$this -> contents = array();
foreach ($temp_list as $t)
{
if (!self::is_hidden($t, !@is_dir($path . $t)))
{
$this -> contents[] = $t;
}
}
$this -> list_count = count($this -> contents);
$this -> i = 0;
}
}
?>

237
classes/DirectoryListDetailed.php Executable file
View File

@@ -0,0 +1,237 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2006 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Subclass of DirectoryList that uses the Item class to represent each
* file/folder in the directory. Each entry in the list is an object of
* the Item class.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.1.0 (January 01, 2006)
* @package AutoIndex
*/
class DirectoryListDetailed extends DirectoryList
{
/**
* @var string The HTML text that makes up the path navigation links
*/
protected $path_nav;
/**
* @var int Total number of files in this directory
*/
protected $total_files;
/**
* @var int Total number of folders in this directory
*/
protected $total_folders;
/**
* @var int Total number of folders in this directory (including parent)
*/
protected $raw_total_folders;
/**
* @var int Total number of downloads of files in this directory
*/
protected $total_downloads;
/**
* @var Size Total size of this directory (recursive)
*/
protected $total_size;
/**
* @return string The HTML text that makes up the path navigation
*/
private function set_path_nav()
{
global $config, $subdir;
$exploded = explode('/', $subdir);
$c = count($exploded) - 1;
$temp = '<a class="autoindex_a" href="' . Url::html_output($_SERVER['PHP_SELF']) . '?dir=">'
. Url::html_output(substr(str_replace('/', ' / ', $config -> __get('base_dir')), 0, -2)) . '</a>/ ';
for ($i = 0; $i < $c; $i++)
{
$temp .= '<a class="autoindex_a" href="' . Url::html_output($_SERVER['PHP_SELF'])
. '?dir=';
for ($j = 0; $j <= $i; $j++)
{
$temp .= Url::translate_uri($exploded[$j]) . '/';
}
$temp .= '">' . Url::html_output($exploded[$i]) . '</a> / ';
}
return $temp;
}
/**
* Returns -1 if $a < $b or 1 if $a > $b
*
* @param Item $a
* @param Item $b
* @return int
*/
private static function callback_sort(Item $a, Item $b)
{
if ($a -> __get('is_parent_dir'))
{
return -1;
}
if ($b -> __get('is_parent_dir'))
{
return 1;
}
$sort = strtolower($_SESSION['sort']);
if ($sort === 'size')
{
$val = (($a -> __get('size') -> __get('bytes') <
$b -> __get('size') -> __get('bytes')) ? -1 : 1);
}
else
{
if (!$a -> is_set($sort))
{
$_SESSION['sort'] = 'filename'; //so the "continue" link will work
throw new ExceptionDisplay('Invalid sort mode.');
}
if (is_string($a -> __get($sort)))
{
$val = strnatcasecmp($a -> __get($sort), $b -> __get($sort));
}
else
{
$val = (($a -> __get($sort) < $b -> __get($sort)) ? -1 : 1);
}
}
return ((strtolower($_SESSION['sort_mode']) === 'd') ? -$val : $val);
}
/**
* @param array $list The array to be sorted with the callback_sort function
*/
protected static function sort_list(&$list)
{
usort($list, array('self', 'callback_sort'));
}
/**
* @return int The total number of files and folders (including the parent folder)
*/
public function total_items()
{
return $this -> raw_total_folders + $this -> total_files;
}
/**
* @param string $path The directory to read the files from
* @param int $page The number of files to skip (used for pagination)
*/
public function __construct($path, $page = 1)
{
$path = Item::make_sure_slash($path);
parent::__construct($path);
$subtract_parent = false;
$this -> total_downloads = $total_size = 0;
$dirs = $files = array();
foreach ($this as $t)
{
if (@is_dir($path . $t))
{
$temp = new DirItem($path, $t);
if ($temp -> __get('is_parent_dir'))
{
$dirs[] = $temp;
$subtract_parent = true;
}
else if ($temp -> __get('filename') !== false)
{
$dirs[] = $temp;
if ($temp -> __get('size') -> __get('bytes') !== false)
{
$total_size += $temp -> __get('size') -> __get('bytes');
}
}
}
else if (@is_file($path . $t))
{
$temp = new FileItem($path, $t);
if ($temp -> __get('filename') !== false)
{
$files[] = $temp;
$this -> total_downloads += $temp -> __get('downloads');
$total_size += $temp -> __get('size') -> __get('bytes');
}
}
}
self::sort_list($dirs);
self::sort_list($files);
$this -> contents = array_merge($dirs, $files);
$this -> total_size = new Size($total_size);
$this -> total_files = count($files);
$this -> raw_total_folders = $this -> total_folders = count($dirs);
if ($subtract_parent)
{
$this -> total_folders--;
}
$this -> path_nav = $this -> set_path_nav();
//Paginate the files
if (ENTRIES_PER_PAGE)
{
if ($page < 1)
{
throw new ExceptionDisplay('Invalid page number.');
}
global $config;
$num_per_page = $config -> __get('entries_per_page');
if (($page - 1) * $num_per_page >= $this -> total_items())
{
throw new ExceptionDisplay('Invalid page number.');
}
$this -> contents = array_slice($this -> contents, ($page - 1) * $num_per_page, $num_per_page);
}
}
/**
* @return string The HTML text of the directory list, using the template system
*/
public function __toString()
{
$head = new TemplateInfo(TABLE_HEADER, $this);
$main = new TemplateFiles(EACH_FILE, $this);
$foot = new TemplateInfo(TABLE_FOOTER, $this);
return $head -> __toString() . $main -> __toString() . $foot -> __toString();
}
}
?>

90
classes/Display.php Executable file
View File

@@ -0,0 +1,90 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Uses the template system to format HTML output, which is then echoed.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.2 (July 22, 2004)
* @package AutoIndex
*/
class Display
{
/**
* @var string HTML text to output
*/
private $contents;
/**
* @return string The HTML text of the list of function calls
* @see debug_backtrace()
*/
public static function get_trace()
{
$list = '<p><strong>Debug trace</strong>:';
foreach (debug_backtrace() as $arr)
{
$line = (isset($arr['line']) ? $arr['line'] : 'unknown');
$file = (isset($arr['file']) ? Item::get_basename($arr['file']) : 'unknown');
$type = (isset($arr['type']) ? $arr['type'] : '');
$class = (isset($arr['class']) ? $arr['class'] : '');
$function = (isset($arr['function']) ? $arr['function'] : 'unknown');
$list .= "\n<br /><em>$file</em> line $line <span class=\"autoindex_small\">($class$type$function)</span>";
}
return $list . '</p>';
}
/**
* @param string $contents Sets the HTML contents
*/
public function __construct(&$contents)
{
$this -> contents = $contents;
}
/**
* @return string The HTML output, using the template system
*/
public function __toString()
{
$header = new Template(GLOBAL_HEADER);
$footer = new Template(GLOBAL_FOOTER);
$output = $header -> __toString() . $this -> contents;
if (DEBUG)
{
$output .= self::get_trace();
}
return $output . $footer -> __toString();
}
}
?>

64
classes/ExceptionDisplay.php Executable file
View File

@@ -0,0 +1,64 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* This is a special Exception that we can display using the template system via
* the Display class.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.0 (August 01, 2004)
* @package AutoIndex
* @see Display
*/
class ExceptionDisplay extends ExceptionFatal
{
/**
* @return string The HTML text to display
*/
public function __toString()
{
global $words;
$str = '<table><tr class="paragraph"><td class="autoindex_td" style="padding: 8px;">'
. $this -> message . '<p><a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']);
if (isset($_GET['dir']))
{
$str .= '?dir=' . Url::translate_uri($_GET['dir']);
}
$str .= '">' . (isset($words) ? $words -> __get('continue') : 'Continue')
. '.</a></p></td></tr></table>';
$temp = new Display($str);
return $temp -> __toString();
}
}
?>

118
classes/FileItem.php Executable file
View File

@@ -0,0 +1,118 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Subclass of item that specifically represents a file.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (July 10, 2004)
* @package AutoIndex
*/
class FileItem extends Item
{
/**
* @param string $fn The filename
* @return string Everything after the list dot in the filename, not including the dot
*/
public static function ext($fn)
{
$fn = Item::get_basename($fn);
return (strpos($fn, '.') ? strtolower(substr(strrchr($fn, '.'), 1)) : '');
}
/**
* @return string Returns the extension of the filename
* @see FileItem::ext()
*/
public function file_ext()
{
return self::ext($this -> filename);
}
/**
* @param string $parent_dir
* @param string $filename
*/
public function __construct($parent_dir, $filename)
{
parent::__construct($parent_dir, $filename);
if (!@is_file($this -> parent_dir . $filename))
{
throw new ExceptionDisplay('File <em>'
. Url::html_output($this -> parent_dir . $filename)
. '</em> does not exist.');
}
global $config, $words, $downloads;
$this -> filename = $filename;
$this -> size = new Size(filesize($this -> parent_dir . $filename));
if (ICON_PATH)
{
$file_icon = new Icon($filename);
$this -> icon = $file_icon -> __toString();
}
$this -> downloads = (DOWNLOAD_COUNT && $downloads -> is_set($parent_dir . $filename) ? (int)($downloads -> __get($parent_dir . $filename)) : 0);
$this -> link = Url::html_output($_SERVER['PHP_SELF']) . '?dir=' . Url::translate_uri(substr($this -> parent_dir, strlen($config -> __get('base_dir'))))
. '&amp;file=' . Url::translate_uri($filename);
if (THUMBNAIL_HEIGHT && in_array(self::ext($filename), array('png', 'jpg', 'jpeg', 'gif')))
{
$this -> thumb_link = ' <img src="' . Url::html_output($_SERVER['PHP_SELF'])
. '?thumbnail='. Url::translate_uri($this -> parent_dir . $filename)
. '" alt="' . $words -> __get('thumbnail of') . ' ' . $filename
. '" />';
}
$size = $this -> size -> __get('bytes');
if (MD5_SHOW && $size > 0 && $size / 1048576 <= $config -> __get('md5_show'))
{
$this -> md5_link = '<span class="autoindex_small">[<a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']) . '?dir='
. Url::translate_uri(substr($this -> parent_dir, strlen($config -> __get('base_dir'))))
. '&amp;md5=' . Url::translate_uri($filename) . '">'
. $words -> __get('calculate md5sum') . '</a>]</span>';
}
}
/**
* @param string $var The key to look for
* @return mixed The data stored at the key
*/
public function __get($var)
{
if (isset($this -> $var))
{
return $this -> $var;
}
throw new ExceptionDisplay('Variable <em>' . Url::html_output($var)
. '</em> not set in FileItem class.');
}
}
?>

155
classes/Ftp.php Executable file
View File

@@ -0,0 +1,155 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2005 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Allows admins to connect to FTP servers and perform various actions.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.0 (February 16, 2005)
* @package AutoIndex
*/
class Ftp extends DirectoryList
{
/**
* @var resource The FTP connection handle
*/
private $handle;
/**
* @var array Array of bools, for each entry
*/
private $is_directory;
/**
* Returns if the $i'th entry is a directory or not.
*
* @param int $i The file/folder entry to check
* @return bool True if directory, false if file
*/
public function is_directory($i)
{
return $this -> is_directory[$i];
}
/**
* Reads the contents of the directory $path from the FTP server.
*
* @param string $path
*/
private function update_list($path)
{
$path = Item::make_sure_slash($path);
$is_dir = $this -> contents = array();
$this -> dir_name = $path;
$raw_list = @ftp_rawlist($this -> handle, $path);
if ($raw_list === false)
{
throw new ExceptionDisplay('Unable to read directory contents of FTP server.');
}
foreach ($raw_list as $file)
{
if ($file == '')
{
continue;
}
$name = strrchr($file, ' ');
if ($name === false)
{
continue;
}
$this -> is_directory[] = (strtolower($file{0}) === 'd');
$this -> contents[] = $path . substr($name, 1);
}
$this -> list_count = count($this -> contents);
$this -> i = 0;
}
/**
* @param string $local
* @param string $remote
*/
public function get_file($local, $remote)
{
if (!@ftp_get($this -> handle, $local, $remote, FTP_BINARY))
{
throw new ExceptionDisplay('Unable to transfer file from FTP server.');
}
}
/**
* @param string $local
* @param string $remote
*/
public function put_file($local, $remote)
{
if (!@ftp_put($this -> handle, $remote, $local, FTP_BINARY))
{
throw new ExceptionDisplay('Unable to transfer file to FTP server.');
}
}
/**
* @param string $host
* @param int $port
* @param bool $passive
* @param string $directory Directory to view
* @param string $username To login with
* @param string $password To login with
*/
public function __construct($host, $port, $passive, $directory, $username, $password)
{
$this -> handle = @ftp_connect(trim($host), (int)$port);
if ($this -> handle === false)
{
throw new ExceptionDisplay('Could not connect to FTP server.');
}
if (!@ftp_login($this -> handle, $username, $password))
{
throw new ExceptionDisplay('Incorrect login for FTP server.');
}
if ($passive && !@ftp_pasv($this -> handle, true))
{
throw new ExceptionDisplay('Could not set passive mode for FTP server.');
}
$this -> update_list($directory);
}
/**
* Closes the open FTP connection when the object is destroyed.
*/
public function __destruct()
{
ftp_close($this -> handle);
}
}
?>

508
classes/Htaccess.php Executable file
View File

@@ -0,0 +1,508 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2007 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Parses .htaccess files and imports their settings to AutoIndex.
*
* These Apache directives are supported:
* - <Directory>
* - <Limit>
* - <IfDefine>
* - AddDescription
* - IndexIgnore
* - Include
* - Order
* - Deny from
* - Allow from
* - AuthUserFile
* - AuthName
* - Require user
*
* These password formats are supported for .htpasswd file:
* - MD5
* - SHA-1
* - Crypt
* - Apache's Custom MD5 Crypt
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (January 6, 2007)
* @package AutoIndex
*/
class Htaccess
{
/**
* @var string "AuthName" setting
*/
private $auth_name;
/**
* @var string "AuthUserFile" setting
*/
private $auth_user_file;
/**
* @var array "Require user" setting
*/
private $auth_required_users;
/**
* @var string "Order" setting
*/
private $order;
/**
* @var array "Allow from" setting
*/
private $allow_list;
/**
* @var array "Deny from" setting
*/
private $deny_list;
/**
* Converts hexadecimal to binary.
*
* @param string $hex
* @return string
*/
private static function hex2bin($hex)
{
$bin = '';
$ln = strlen($hex);
for($i = 0; $i < $ln; $i += 2)
{
$bin .= chr(hexdec($hex{$i} . $hex{$i+1}));
}
return $bin;
}
/**
* Return the number of count from the value using base conversion.
*
* @param int $value
* @param int $count
* @return int
*/
private static function to64($value, $count)
{
static $root = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$result = '';
while(--$count)
{
$result .= $root[$value & 0x3f];
$value >>= 6;
}
return $result;
}
/**
* Implementation of Apache's Custom MD5 Crypt.
*
* @param string $plain The plaintext password
* @param string $salt The salt
* @return string The hashed password
*/
private static function md5_crypt($plain, $salt)
{
$length = strlen($plain);
$context = $plain . '$apr1$' . $salt;
$binary = self::hex2bin(md5($plain . $salt . $plain));
for ($i = $length; $i > 0; $i -= 16)
{
$context .= substr($binary, 0, min(16, $i));
}
for ( $i = $length; $i > 0; $i >>= 1)
{
$context .= ($i & 1) ? chr(0) : $plain[0];
}
$binary = self::hex2bin(md5($context));
for ($i = 0; $i < 1000; $i++)
{
$new = ($i & 1) ? $plain : substr($binary, 0, 16);
if ($i % 3)
{
$new .= $salt;
}
if ($i % 7)
{
$new .= $plain;
}
$new .= (($i & 1) ? substr($binary, 0, 16) : $plain);
$binary = self::hex2bin(md5($new));
}
$p = array();
for ($i = 0; $i < 5; $i++)
{
$k = $i + 6;
$j = $i + 12;
if ($j == 16)
{
$j = 5;
}
$p[] = self::to64(
(ord($binary[$i]) << 16) |
(ord($binary[$k]) << 8) |
(ord($binary[$j])), 5
);
}
return '$apr1$' . $salt . '$' . implode($p) . self::to64(ord($binary[11]), 3);
}
/**
* Tests if $test matches $target.
*
* @param string $test
* @param string $target
* @return bool True if $test matches $target
*/
private static function matches($test, $target)
{
static $replace = array(
'\*' => '.*',
'\+' => '.+',
'\?' => '.?');
return (bool)preg_match('/^' . strtr(preg_quote($test, '/'), $replace) . '$/i', $target);
}
/**
* Checks if AuthName and AuthUserFile are set, and then prompts for a
* username and password.
*/
private function check_auth()
{
if ($this -> auth_user_file == '')
{
return;
}
if ($this -> auth_name == '')
{
$this -> auth_name = '"Directory access restricted by AutoIndex"';
}
$validated = false;
if (isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']))
{
$file = @file($this -> auth_user_file);
if ($file === false)
{
$_GET['dir'] = '';
throw new ExceptionDisplay('Cannot open .htpasswd file.
<br /><em>' . htmlentities($this -> auth_user_file) . '</em>');
}
if ($this -> auth_required_users === array() || DirectoryList::match_in_array($_SERVER['PHP_AUTH_USER'], $this -> auth_required_users))
{
foreach ($file as $account)
{
$parts = explode(':', trim($account));
if (count($parts) < 2 || $_SERVER['PHP_AUTH_USER'] != $parts[0])
{
continue;
}
if (isset($parts[2]))
//MD5 hash format with realm
{
$parts[1] = $parts[2];
}
switch (strlen($parts[1]))
{
case 13:
//Crypt hash format
{
$validated = (crypt($_SERVER['PHP_AUTH_PW'], substr($parts[1], 0, 2)) == $parts[1]);
break 2;
}
case 32:
//MD5 hash format
{
$validated = (md5($_SERVER['PHP_AUTH_PW']) == $parts[1]);
break 2;
}
case 37:
//Apache's MD5 Crypt hash format
{
$salt = explode('$', $parts[1]);
$validated = (self::md5_crypt($_SERVER['PHP_AUTH_PW'], $salt[2]) == $parts[1]);
break 2;
}
case 40:
//SHA-1 hash format
{
$validated = (sha1($_SERVER['PHP_AUTH_PW']) == $parts[1]);
break 2;
}
}
}
}
sleep(1);
}
if (!$validated)
{
header('WWW-Authenticate: Basic realm=' . $this -> auth_name);
header('HTTP/1.0 401 Authorization Required');
$_GET['dir'] = '';
throw new ExceptionDisplay('A username and password are required to access this directory.');
}
}
/**
* Checks if the user's IP or hostname is either allowed or denied.
*/
private function check_deny()
{
global $ip, $host, $words;
if ($this -> order === 'allow,deny')
{
if (!DirectoryList::match_in_array($host, $this -> allow_list)
&& !DirectoryList::match_in_array($ip, $this -> allow_list))
{
$_GET['dir'] = '';
throw new ExceptionDisplay($words -> __get('the administrator has blocked your ip address or hostname') . '.');
}
}
else if (DirectoryList::match_in_array($ip, $this -> deny_list)
|| DirectoryList::match_in_array($host, $this -> deny_list))
{
$_GET['dir'] = '';
throw new ExceptionDisplay($words -> __get('the administrator has blocked your ip address or hostname') . '.');
}
}
/**
* @param string $file The .htaccess file (name and path) to parse
*/
private function parse($file)
{
$data = @file($file);
if ($data === false)
{
return;
}
$conditional_directory = '';
$other_conditional = false;
foreach ($data as $line)
{
$line = trim($line);
if ($line == '')
{
continue;
}
if ($line{0} == '<')
{
if (preg_match('#^</\s*directory.*?>#i', $line))
{
$conditional_directory = '';
}
else if (preg_match('#^<\s*directory\s+\"?(.+?)\"?\s*>#i', $line, $matches))
{
$conditional_directory = $matches[1];
}
else if (preg_match('#^</?\s*limit.*?>#i', $line))
{
//ignore <Limit> tags
continue;
}
else if (preg_match('#^</\s*ifdefine.*?>#i', $line))
{
$conditional_defined = '';
}
else if (preg_match('#^<\s*ifdefine\s+(.+?)\s*>#i', $line, $matches))
{
$conditional_defined = $matches[1];
}
else if (isset($line{1}))
{
$other_conditional = ($line{1} != '/');
}
continue;
}
global $dir;
if ($other_conditional || $conditional_directory != '' && !self::matches($conditional_directory, $dir))
//deal with <Directory> or an unknown < > tag
{
continue;
}
if ($conditional_defined != '')
//deal with <IfDefine>
{
$conditional_defined = strtoupper($conditional_defined);
if ($conditional_defined{0} === '!')
{
$conditional_defined = substr($conditional_defined, 1);
if (defined($conditional_defined) && constant($conditional_defined))
{
continue;
}
}
else if (!defined($conditional_defined) || !constant($conditional_defined))
{
continue;
}
}
$parts = preg_split('#\s#', $line, -1, PREG_SPLIT_NO_EMPTY);
switch (strtolower($parts[0]))
{
case 'indexignore':
{
global $hidden_files;
for ($i = 1; $i < count($parts); $i++)
{
$hidden_files[] = $parts[$i];
}
break;
}
case 'include':
{
if (isset($parts[1]) && @is_file($parts[1]) && @is_readable($parts[1]))
{
self::parse($parts[1]);
}
break;
}
case 'allow':
{
if (isset($parts[1]) && strtolower($parts[1]) === 'from')
{
for ($i = 2; $i < count($parts); $i++)
{
foreach (explode(',', $parts[$i]) as $ip)
{
if (strtolower($ip) === 'all')
{
$this -> allow_list = array('*');
}
else
{
$this -> allow_list[] = $ip;
}
}
}
}
break;
}
case 'deny':
{
if (isset($parts[1]) && strtolower($parts[1]) === 'from')
{
for ($i = 2; $i < count($parts); $i++)
{
foreach (explode(',', $parts[$i]) as $ip)
{
if (strtolower($ip) === 'all')
{
$this -> deny_list = array('*');
}
else
{
$this -> deny_list[] = $ip;
}
}
}
}
break;
}
case 'adddescription':
{
global $descriptions;
if (!isset($descriptions))
{
$descriptions = new ConfigData(false);
}
for ($i = 1; isset($parts[$i], $parts[$i+1]); $i += 2)
{
$descriptions -> set($parts[$i], $parts[$i+1]);
}
break;
}
case 'authuserfile':
{
if (isset($parts[1]))
{
$this -> auth_user_file = str_replace('"', '', implode(' ', array_slice($parts, 1)));
}
break;
}
case 'authname':
{
if (isset($parts[1]))
{
$this -> auth_name = implode(' ', array_slice($parts, 1));
}
break;
}
case 'order':
{
if (isset($parts[1]) && (strtolower($parts[1]) === 'allow,deny' || strtolower($parts[1]) === 'mutual-failure'))
{
$this -> order = 'allow,deny';
}
}
case 'require':
{
if (isset($parts[1]) && strtolower($parts[1]) === 'user')
{
for ($i = 2; $i < count($parts); $i++)
{
$this -> auth_required_users[] = $parts[$i];
}
}
break;
}
}
}
}
/**
* @param string $dir The deepest folder to parse for .htaccess files
* @param string $filename The name of the files to look for
*/
public function __construct($dir, $filename = '.htaccess')
{
$this -> auth_name = $this -> auth_user_file = '';
$this -> auth_required_users = $this -> allow_list = $this -> deny_list = array();
$this -> order = 'deny,allow';
if (DirItem::get_parent_dir($dir) != '')
//recurse into parent directories
{
new Htaccess(DirItem::get_parent_dir($dir));
}
$dir = Item::make_sure_slash($dir);
$file = $dir . $filename;
if (@is_file($file) && @is_readable($file))
{
$this -> parse($dir . $filename);
$this -> check_deny();
$this -> check_auth();
}
}
}
?>

148
classes/Icon.php Executable file
View File

@@ -0,0 +1,148 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Given a filename, this will come up with an icon to represent the filetype.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.2 (August 07, 2004)
* @package AutoIndex
*/
class Icon
{
/**
* @var string Filename of the image file
*/
private $image_name;
/**
* Given a file extension, this will come up with the filename of the
* icon to represent the filetype.
*
* @param string $ext The file extension to find the icon for
* @return string The appropriate icon depending on the extension
*/
private static function find_icon($ext)
{
if ($ext == '')
{
return 'generic';
}
static $icon_types = array(
'binary' => array('bat', 'bin', 'com', 'dmg', 'dms', 'exe', 'msi',
'msp', 'pif', 'pyd', 'scr', 'so'),
'binhex' => array('hqx'),
'cd' => array('bwi', 'bws', 'bwt', 'ccd', 'cdi', 'cue', 'img',
'iso', 'mdf', 'mds', 'nrg', 'nri', 'sub', 'vcd'),
'comp' => array('cfg', 'conf', 'inf', 'ini', 'log', 'nfo', 'reg'),
'compressed' => array('7z', 'a', 'ace', 'ain', 'alz', 'amg', 'arc',
'ari', 'arj', 'bh', 'bz', 'bz2', 'cab', 'deb', 'dz', 'gz',
'io', 'ish', 'lha', 'lzh', 'lzs', 'lzw', 'lzx', 'msx', 'pak',
'rar', 'rpm', 'sar', 'sea', 'sit', 'taz', 'tbz', 'tbz2',
'tgz', 'tz', 'tzb', 'uc2', 'xxe', 'yz', 'z', 'zip', 'zoo'),
'dll' => array('386', 'db', 'dll', 'ocx', 'sdb', 'vxd'),
'doc' => array('abw', 'ans', 'chm', 'cwk', 'dif', 'doc', 'dot',
'mcw', 'msw', 'pdb', 'psw', 'rtf', 'rtx', 'sdw', 'stw', 'sxw',
'vor', 'wk4', 'wkb', 'wpd', 'wps', 'wpw', 'wri', 'wsd'),
'image' => array('adc', 'art', 'bmp', 'cgm', 'dib', 'gif', 'ico',
'ief', 'jfif', 'jif', 'jp2', 'jpc', 'jpe', 'jpeg', 'jpg', 'jpx',
'mng', 'pcx', 'png', 'psd', 'psp', 'swc', 'sxd', 'tga',
'tif', 'tiff', 'wmf', 'wpg', 'xcf', 'xif', 'yuv'),
'java' => array('class', 'jar', 'jav', 'java', 'jtk'),
'js' => array('ebs', 'js', 'jse', 'vbe', 'vbs', 'wsc', 'wsf',
'wsh'),
'key' => array('aex', 'asc', 'gpg', 'key', 'pgp', 'ppk'),
'mov' => array('amc', 'dv', 'm4v', 'mac', 'mov', 'mp4v', 'mpg4',
'pct', 'pic', 'pict', 'pnt', 'pntg', 'qpx', 'qt', 'qti',
'qtif', 'qtl', 'qtp', 'qts', 'qtx'),
'movie' => array('asf', 'asx', 'avi', 'div', 'divx', 'dvi', 'm1v',
'm2v', 'mkv', 'movie', 'mp2v', 'mpa', 'mpe', 'mpeg', 'mpg',
'mps', 'mpv', 'mpv2', 'ogm', 'ram', 'rmvb', 'rnx', 'rp', 'rv',
'vivo', 'vob', 'wmv', 'xvid'),
'pdf' => array('edn', 'fdf', 'pdf', 'pdp', 'pdx'),
'php' => array('inc', 'php', 'php3', 'php4', 'php5', 'phps',
'phtml'),
'ppt' => array('emf', 'pot', 'ppa', 'pps', 'ppt', 'sda', 'sdd',
'shw', 'sti', 'sxi'),
'ps' => array('ai', 'eps', 'ps'),
'sound' => array('aac', 'ac3', 'aif', 'aifc', 'aiff', 'ape', 'apl',
'au', 'ay', 'bonk', 'cda', 'cdda', 'cpc', 'fla', 'flac',
'gbs', 'gym', 'hes', 'iff', 'it', 'itz', 'kar', 'kss', 'la',
'lpac', 'lqt', 'm4a', 'm4p', 'mdz', 'mid', 'midi', 'mka',
'mo3', 'mod', 'mp+', 'mp1', 'mp2', 'mp3', 'mp4', 'mpc',
'mpga', 'mpm', 'mpp', 'nsf', 'oda', 'ofr', 'ogg', 'pac', 'pce',
'pcm', 'psf', 'psf2', 'ra', 'rm', 'rmi', 'rmjb', 'rmm', 'sb',
'shn', 'sid', 'snd', 'spc', 'spx', 'svx', 'tfm', 'tfmx',
'voc', 'vox', 'vqf', 'wav', 'wave', 'wma', 'wv', 'wvx', 'xa',
'xm', 'xmz'),
'tar' => array('gtar', 'tar'),
'text' => array('asm', 'c', 'cc', 'cp', 'cpp', 'cxx', 'diff', 'h',
'hpp', 'hxx', 'm3u', 'md5', 'patch', 'pls', 'py', 'sfv', 'sh',
'txt'),
'uu' => array('uu', 'uud', 'uue'),
'web' => array('asa', 'asp', 'aspx', 'cfm', 'cgi', 'css', 'dhtml',
'dtd', 'grxml', 'htc', 'htm', 'html', 'htt', 'htx', 'jsp', 'lnk',
'mathml', 'mht', 'mhtml', 'perl', 'pl', 'plg', 'rss', 'shtm',
'shtml', 'stm', 'swf', 'tpl', 'wbxml', 'xht', 'xhtml', 'xml',
'xsl', 'xslt', 'xul'),
'xls' => array('csv', 'dbf', 'prn', 'pxl', 'sdc', 'slk', 'stc', 'sxc',
'xla', 'xlb', 'xlc', 'xld', 'xlr', 'xls', 'xlt', 'xlw'));
foreach ($icon_types as $png_name => $exts)
{
if (in_array($ext, $exts))
{
return $png_name;
}
}
return 'unknown';
}
/**
* @param string $filename The filename to find the icon for
*/
public function __construct($filename)
{
$this -> image_name = self::find_icon(FileItem::ext($filename));
}
/**
* @return string The full path to the icon file
*/
public function __toString()
{
global $config;
return $config -> __get('icon_path')
. $this -> image_name . '.png';
}
}
?>

133
classes/Image.php Executable file
View File

@@ -0,0 +1,133 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Generates a thumbnail of an image file.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.0 (May 22, 2004)
* @package AutoIndex
*/
class Image
{
/**
* @var string Name of the image file
*/
private $filename;
/**
* @var int The height of the thumbnail to create (width is automatically determined)
*/
private $height;
/**
* Outputs the jpeg image along with the correct headers so the
* browser will display it. The script is then exited.
*/
public function __toString()
{
$thumbnail_height = $this -> height;
$file = $this -> filename;
if (!@is_file($file))
{
header('HTTP/1.0 404 Not Found');
throw new ExceptionDisplay('Image file not found: <em>'
. Url::html_output($file) . '</em>');
}
switch (FileItem::ext($file))
{
case 'gif':
{
$src = @imagecreatefromgif($file);
break;
}
case 'jpeg':
case 'jpg':
case 'jpe':
{
$src = @imagecreatefromjpeg($file);
break;
}
case 'png':
{
$src = @imagecreatefrompng($file);
break;
}
default:
{
throw new ExceptionDisplay('Unsupported file extension.');
}
}
if ($src === false)
{
throw new ExceptionDisplay('Unsupported image type.');
}
header('Content-Type: image/jpeg');
header('Cache-Control: public, max-age=3600, must-revalidate');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600)
. ' GMT');
$src_height = imagesy($src);
if ($src_height <= $thumbnail_height)
{
imagejpeg($src, '', 95);
}
else
{
$src_width = imagesx($src);
$thumb_width = $thumbnail_height * ($src_width / $src_height);
$thumb = imagecreatetruecolor($thumb_width, $thumbnail_height);
imagecopyresampled($thumb, $src, 0, 0, 0, 0, $thumb_width,
$thumbnail_height, $src_width, $src_height);
imagejpeg($thumb);
imagedestroy($thumb);
}
imagedestroy($src);
die();
}
/**
* @param string $file The image file
*/
public function __construct($file)
{
if (!THUMBNAIL_HEIGHT)
{
throw new ExceptionDisplay('Image thumbnailing is turned off.');
}
global $config;
$this -> height = (int)$config -> __get('thumbnail_height');
$this -> filename = $file;
}
}
?>

218
classes/Item.php Executable file
View File

@@ -0,0 +1,218 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Abstract class to represent either a file or a directory.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (July 03, 2004)
* @package AutoIndex
* @see DirItem, FileItem
*/
abstract class Item
{
/**
* @var string
*/
protected $filename;
/**
* @var Size
*/
protected $size;
/**
* @var int Last modified time
*/
protected $m_time;
/**
* @var int Last accessed time
*/
protected $a_time;
/**
* @var int
*/
protected $downloads;
/**
* @var string
*/
protected $description;
/**
* @var string The HTML text of the link to the type icon
*/
protected $icon;
/**
* @var string The HTML text of the "[New]" icon
*/
protected $new_icon;
/**
* @var string The HTML text of the link to this file or folder
*/
protected $link;
/**
* @var string The HTML text of the link to the thumbnail picture
*/
protected $thumb_link;
/**
* @var string The HTML text of the link to find the md5sum
*/
protected $md5_link;
/**
* @var string The name and path of the parent directory
*/
protected $parent_dir;
/**
* @var bool True if this is a link to '../'
*/
protected $is_parent_dir;
/**
* @param int $timestamp Time in UNIX timestamp format
* @return string Formatted version of $timestamp
*/
private static function format_date($timestamp)
{
if ($timestamp === false)
{
return '&nbsp;';
}
return date(DATE_FORMAT, $timestamp);
}
/**
* @return string Date modified (m_time) formatted as a string
* @see Item::format_date()
*/
public function format_m_time()
{
return self::format_date($this -> m_time);
}
/**
* @return string Date last accessed (a_time) formatted as a string
* @see Item::format_date()
*/
public function format_a_time()
{
return self::format_date($this -> a_time);
}
/**
* Returns everything after the slash, or the original string if there is
* no slash. A slash at the last character of the string is ignored.
*
* @param string $fn The file or folder name
* @return string The basename of $fn
* @see basename()
*/
public static function get_basename($fn)
{
return basename(str_replace('\\', '/', $fn));
}
/**
* @param string $path The directory name
* @return string If there is no slash at the end of $path, one will be added
*/
public static function make_sure_slash($path)
{
$path = str_replace('\\', '/', $path);
if (!preg_match('#/$#', $path))
{
$path .= '/';
}
return $path;
}
/**
* @param string $parent_dir
* @param string $filename
*/
public function __construct($parent_dir, $filename)
{
$parent_dir = self::make_sure_slash($parent_dir);
$full_name = $parent_dir . $filename;
$this -> is_parent_dir = false;
$this -> m_time = filemtime($full_name);
$this -> a_time = fileatime($full_name);
$this -> icon = $this -> new_icon = $this -> md5_link = $this -> thumb_link = '';
global $descriptions;
$this -> description = ((DESCRIPTION_FILE && $descriptions -> is_set($full_name)) ? $descriptions -> __get($full_name) : '&nbsp;');
$this -> parent_dir = $parent_dir;
if (DAYS_NEW)
{
global $config;
$days_new = $config -> __get('days_new');
$age = (time() - $this -> m_time) / 86400;
$age_r = round($age, 1);
$s = (($age_r == 1) ? '' : 's');
$this -> new_icon = (($days_new > 0 && $age <= $days_new) ?
(ICON_PATH ? ' <img src="' . $config -> __get('icon_path')
. 'new.png" alt="' . "$age_r day$s" . ' old" height="14" width="28" />' : ' <span class="autoindex_small" style="color: #FF0000;">[New]</span>') : '');
}
}
/**
* @param string $var The key to look for
* @return bool True if $var is set
*/
public function is_set($var)
{
return isset($this -> $var);
}
/**
* @return string The file or folder name
*/
public function __toString()
{
return $this -> filename;
}
/**
* @return string The file extension of the file or folder name
*/
abstract public function file_ext();
}
?>

164
classes/Language.php Executable file
View File

@@ -0,0 +1,164 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2006 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Represents a language file.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.0 (January 01, 2006)
* @package AutoIndex
*/
class Language
{
/**
* @var ConfigData Contains the translation data from the language file
*/
private $translation_data;
/**
* Returns a list of all files in $path that match the filename format
* of language files.
*
* There are two valid formats for the filename of a language file. The
* standard way is the language code then the .txt extension. You can
* also use the language code followed by an underscore then the
* country code. The second format would be used for dialects of
* languages. For example pt.txt would be Portuguese, and pt_BR.txt
* would be Brazilian Portuguese. The filenames are case insensitive.
*
* @param string $path The directory to read from
* @return array The list of valid language files (based on filename)
*/
public static function get_all_langs($path)
{
if (($hndl = @opendir($path)) === false)
{
return false;
}
$list = array();
while (($file = readdir($hndl)) !== false)
{
if (@is_file($path . $file) && preg_match('/^[a-z]{2}(_[a-z]{2})?'
. preg_quote(LANGUAGE_FILE_EXT, '/') . '$/i', $file))
{
$list[] = $file;
}
}
closedir($hndl);
for ($i = 0; $i < count($list); $i++)
{
//remove the file extention from each language code
$list[$i] = substr($list[$i], 0, -strlen(LANGUAGE_FILE_EXT));
}
return $list;
}
/**
* @return string The code for the language to load
*
* First tries to use the default of the user's browser, and then tries
* the default in the config file.
*/
private function get_current_lang()
{
//try to detect the default language of the user's browser
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
//e.g. "en-us,en;q=0.5"
{
$available_langs = self::get_all_langs(PATH_TO_LANGUAGES);
if ($available_langs !== false)
{
$pref = array(); //user's preferred languages
foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $lang)
{
$lang_array = explode(';q=', trim($lang));
$q = (isset($lang_array[1]) ? trim($lang_array[1]) : 1); //preference value
$pref[trim($lang_array[0])] = (float)$q;
}
arsort($pref);
//find the first match that is available:
foreach ($pref as $lang => $q)
{
if (in_array($lang, $available_langs))
{
return $lang;
}
}
}
}
//the browser has no preferences set, so use the config's default
global $config;
return $config -> __get('language');
}
/**
* Creates a new language object. First tries to use the default of
* the user's browser, and then tries the default in the config file.
*/
public function __construct()
{
$lang_file = PATH_TO_LANGUAGES . $this -> get_current_lang()
. LANGUAGE_FILE_EXT;
if (!@is_readable($lang_file))
{
throw new ExceptionFatal('Cannot read from language file: <em>'
. Url::html_output($lang_file) . '</em>');
}
//load the file as a tab-separated object
$this -> translation_data = new ConfigData($lang_file);
}
/**
* @param string $name The word to look for
* @return bool True if $name is set in the translation file
*/
public function is_set($name)
{
return $translation_data -> is_set($name);
}
/**
* @param string $var The key to look for (the keyword)
* @return string The value $name points to (its translation)
*/
public function __get($var)
{
if ($this -> translation_data -> is_set($var))
{
return $this -> translation_data -> __get($var);
}
throw new ExceptionDisplay('Variable <em>' . Url::html_output($var)
. '</em> not set in Language file.');
}
}
?>

132
classes/Logging.php Executable file
View File

@@ -0,0 +1,132 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Allows information to be written to the log file.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (July 21, 2004)
* @package AutoIndex
*/
class Logging
{
/**
* @var string Filename of the log to write to
*/
private $filename;
/**
* @param string $filename The name of the log file
*/
public function __construct($filename)
{
$this -> filename = $filename;
}
/**
* Writes data to the log file.
*
* @param string $extra Any additional data to add in the last column of the entry
*/
public function add_entry($extra = '')
{
if (LOG_FILE)
{
$h = @fopen($this -> filename, 'ab');
if ($h === false)
{
throw new ExceptionDisplay('Could not open log file for writing.'
. ' Make sure PHP has write permission to this file.');
}
global $dir, $ip, $host;
$referrer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'N/A');
fwrite($h, date(DATE_FORMAT) . "\t" . date('H:i:s')
. "\t$ip\t$host\t$referrer\t$dir\t$extra\n");
fclose($h);
}
}
/**
* @param int $max_num_to_display
*/
public function display($max_num_to_display)
{
if (!@is_file($this -> filename))
{
throw new ExceptionDisplay('There are no entries in the log file.');
}
$file_array = @file($this -> filename);
if ($file_array === false)
{
throw new ExceptionDisplay('Could not open log file for reading.');
}
$count_log = count($file_array);
$num = (($max_num_to_display == 0) ? $count_log : min($max_num_to_display, $count_log));
$out = "<p>Viewing $num (of $count_log) entries.</p>\n"
. '<table cellpadding="4"><tr class="autoindex_th">'
. '<th>#</th><th>Date</th><th>Time</th>'
. '<th>IP address</th><th>Hostname</th>'
. '<th>Referrer</th><th>Directory</th>'
. '<th>File downloaded or other info</th></tr>';
for ($i = 0; $i < $num; $i++)
{
$class = (($i % 2) ? 'dark_row' : 'light_row');
$out .= '<tr><th style="border: 1px solid; border-color: #7F8FA9;" class="'
. $class . '">' . ($i + 1) . '</th>';
$parts = explode("\t", rtrim($file_array[$count_log-$i-1], "\r\n"), 7);
if (count($parts) !== 7)
{
throw new ExceptionDisplay('Incorrect format for log file on line '
. ($i + 1));
}
for ($j = 0; $j < 7; $j++)
{
$cell = Url::html_output($parts[$j]);
if ($j === 4 && $cell != 'N/A')
{
$cell = "<a class=\"autoindex_a\" href=\"$cell\">$cell</a>";
}
$out .= '<td style="border: 1px solid; border-color: #7F8FA9;" class="'
. $class . '">' . (($cell == '') ? '&nbsp;</td>' : "$cell</td>");
}
$out .= "</tr>\n";
}
global $words;
$out .= '</table><p><a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']) . '">' . $words -> __get('continue')
. '.</a></p>';
echo new Display($out);
die();
}
}
?>

200
classes/MimeType.php Executable file
View File

@@ -0,0 +1,200 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2005 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Given a filename extension, this will come up with the appropriate MIME-type.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (February 09, 2005)
* @package AutoIndex
*/
class MimeType
{
/**
* @var string The filename's MIME-type
*/
private $mime;
/**
* @var string The default MIME-type to return
*/
private $default_type;
/**
* Given a file extension, this will come up with the file's appropriate
* MIME-type.
*
* @param string $ext The file extension to find the MIME-type for
* @return string The appropriate MIME-type depending on the extension
*/
private function find_mime_type($ext)
{
static $mime_types = array(
'application/andrew-inset' => array('ez'),
'application/mac-binhex40' => array('hqx'),
'application/mac-compactpro' => array('cpt'),
'application/mathml+xml' => array('mathml'),
'application/msword' => array('doc'),
'application/octet-stream' => array('bin', 'dms', 'lha',
'lzh', 'exe', 'class', 'so', 'dll', 'dmg'),
'application/oda' => array('oda'),
'application/ogg' => array('ogg'),
'application/pdf' => array('pdf'),
'application/postscript' => array('ai', 'eps', 'ps'),
'application/rdf+xml' => array('rdf'),
'application/smil' => array('smi', 'smil'),
'application/srgs' => array('gram'),
'application/srgs+xml' => array('grxml'),
'application/vnd.mif' => array('mif'),
'application/vnd.mozilla.xul+xml' => array('xul'),
'application/vnd.ms-excel' => array('xls'),
'application/vnd.ms-powerpoint' => array('ppt'),
'application/vnd.wap.wbxml' => array('wbxml'),
'application/vnd.wap.wmlc' => array('wmlc'),
'application/vnd.wap.wmlscriptc' => array('wmlsc'),
'application/voicexml+xml' => array('vxml'),
'application/x-bcpio' => array('bcpio'),
'application/x-cdlink' => array('vcd'),
'application/x-chess-pgn' => array('pgn'),
'application/x-cpio' => array('cpio'),
'application/x-csh' => array('csh'),
'application/x-director' => array('dcr', 'dir', 'dxr'),
'application/x-dvi' => array('dvi'),
'application/x-futuresplash' => array('spl'),
'application/x-gtar' => array('gtar'),
'application/x-hdf' => array('hdf'),
'application/x-javascript' => array('js'),
'application/x-koan' => array('skp', 'skd', 'skt', 'skm'),
'application/x-latex' => array('latex'),
'application/x-netcdf' => array('nc', 'cdf'),
'application/x-sh' => array('sh'),
'application/x-shar' => array('shar'),
'application/x-shockwave-flash' => array('swf'),
'application/x-stuffit' => array('sit'),
'application/x-sv4cpio' => array('sv4cpio'),
'application/x-sv4crc' => array('sv4crc'),
'application/x-tar' => array('tar'),
'application/x-tcl' => array('tcl'),
'application/x-tex' => array('tex'),
'application/x-texinfo' => array('texinfo', 'texi'),
'application/x-troff' => array('t', 'tr', 'roff'),
'application/x-troff-man' => array('man'),
'application/x-troff-me' => array('me'),
'application/x-troff-ms' => array('ms'),
'application/x-ustar' => array('ustar'),
'application/x-wais-source' => array('src'),
'application/xhtml+xml' => array('xhtml', 'xht'),
'application/xslt+xml' => array('xslt'),
'application/xml' => array('xml', 'xsl'),
'application/xml-dtd' => array('dtd'),
'application/zip' => array('zip'),
'audio/basic' => array('au', 'snd'),
'audio/midi' => array('mid', 'midi', 'kar'),
'audio/mpeg' => array('mpga', 'mp2', 'mp3'),
'audio/x-aiff' => array('aif', 'aiff', 'aifc'),
'audio/x-mpegurl' => array('m3u'),
'audio/x-pn-realaudio' => array('ram', 'ra'),
'application/vnd.rn-realmedia' => array('rm'),
'audio/x-wav' => array('wav'),
'chemical/x-pdb' => array('pdb'),
'chemical/x-xyz' => array('xyz'),
'image/bmp' => array('bmp'),
'image/cgm' => array('cgm'),
'image/gif' => array('gif'),
'image/ief' => array('ief'),
'image/jpeg' => array('jpeg', 'jpg', 'jpe'),
'image/png' => array('png'),
'image/svg+xml' => array('svg'),
'image/tiff' => array('tiff', 'tif'),
'image/vnd.djvu' => array('djvu', 'djv'),
'image/vnd.wap.wbmp' => array('wbmp'),
'image/x-cmu-raster' => array('ras'),
'image/x-icon' => array('ico'),
'image/x-portable-anymap' => array('pnm'),
'image/x-portable-bitmap' => array('pbm'),
'image/x-portable-graymap' => array('pgm'),
'image/x-portable-pixmap' => array('ppm'),
'image/x-rgb' => array('rgb'),
'image/x-xbitmap' => array('xbm'),
'image/x-xpixmap' => array('xpm'),
'image/x-xwindowdump' => array('xwd'),
'model/iges' => array('igs', 'iges'),
'model/mesh' => array('msh', 'mesh', 'silo'),
'model/vrml' => array('wrl', 'vrml'),
'text/calendar' => array('ics', 'ifb'),
'text/css' => array('css'),
'text/html' => array('html', 'htm'),
'text/plain' => array('asc', 'txt'),
'text/richtext' => array('rtx'),
'text/rtf' => array('rtf'),
'text/sgml' => array('sgml', 'sgm'),
'text/tab-separated-values' => array('tsv'),
'text/vnd.wap.wml' => array('wml'),
'text/vnd.wap.wmlscript' => array('wmls'),
'text/x-setext' => array('etx'),
'video/mpeg' => array('mpeg', 'mpg', 'mpe'),
'video/quicktime' => array('qt', 'mov'),
'video/vnd.mpegurl' => array('mxu', 'm4u'),
'video/x-msvideo' => array('avi'),
'video/x-sgi-movie' => array('movie'),
'x-conference/x-cooltalk' => array('ice')
);
foreach ($mime_types as $mime_type => $exts)
{
if (in_array($ext, $exts))
{
return $mime_type;
}
}
return $this -> default_type;
}
/**
* @param string $filename The filename to find the MIME-type for
* @param string $default_type The default MIME-type to return
*/
public function __construct($filename, $default_type = 'text/plain')
{
$this -> default_type = $default_type;
$this -> mime = $this -> find_mime_type(FileItem::ext($filename));
}
/**
* @return string
*/
public function __toString()
{
return $this -> mime;
}
}
?>

189
classes/Search.php Executable file
View File

@@ -0,0 +1,189 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2005 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Similar to DirectoryListDetailed, except this filters out certain
* entries based on filename.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.3 (July 06, 2005)
* @package AutoIndex
*/
class Search extends DirectoryListDetailed
{
/**
* @var array List of matched filenames
*/
private $matches;
/**
* @return string The HTML text that makes up the search box
*/
public static function search_box()
{
global $words, $subdir;
$search = (isset($_GET['search']) ? Url::html_output($_GET['search']) : '');
$mode = (isset($_GET['search_mode']) ? self::clean_mode($_GET['search_mode']) : 'f');
$modes = array('files' => 'f', 'folders' => 'd', 'both' => 'fd');
$out = '<form action="' . Url::html_output($_SERVER['PHP_SELF']) . '" method="get">'
. '<p><input type="hidden" name="dir" value="' . $subdir . '" />'
. '<input type="text" name="search" value="' . $search
. '" /><br /><select name="search_mode">';
foreach ($modes as $word => $m)
{
$sel = (($m == $mode) ? ' selected="selected"' : '');
$out .= '<option value="' . $m . '"' . $sel . '>'
. $words -> __get($word) . '</option>';
}
$out .= '</select><input type="submit" class="button" value="'
. $words -> __get('search') . '" /></p></form>';
return $out;
}
/**
* @param string $filename
* @param string $string
* @return bool True if string matches filename
*/
private static function match(&$filename, &$string)
{
if (preg_match_all('/(?<=")[^"]+(?=")|[^ "]+/', $string, $matches))
{
foreach ($matches[0] as $w)
{
if (stripos($filename, $w) !== false)
{
return true;
}
}
}
return false;
}
/**
* Merges $obj into $this.
*
* @param Search $obj
*/
private function merge(Search $obj)
{
$this -> total_folders += $obj -> __get('total_folders');
$this -> total_files += $obj -> __get('total_files');
$this -> total_downloads += $obj -> __get('total_downloads');
$this -> total_size -> add_size($obj -> __get('total_size'));
$this -> matches = array_merge($this -> matches, $obj -> __get('contents'));
}
/**
* Returns a string with all characters except 'd' and 'f' stripped.
* Either 'd' 'f' 'df' will be returned, defaults to 'f'
*
* @param string $mode
* @return string
*/
private static function clean_mode($mode)
{
$str = '';
if (stripos($mode, 'f') !== false)
{
$str .= 'f';
}
if (stripos($mode, 'd') !== false)
{
$str .= 'd';
}
else if ($str == '')
{
$str = 'f';
}
return $str;
}
/**
* @param string $query String to search for
* @param string $dir The folder to search (recursive)
* @param string $mode Should be f (files), d (directories), or fd (both)
*/
public function __construct($query, $dir, $mode)
{
if (strlen($query) < 2 || strlen($query) > 20)
{
throw new ExceptionDisplay('Search query is either too long or too short.');
}
$mode = self::clean_mode($mode);
$dir = Item::make_sure_slash($dir);
DirectoryList::__construct($dir);
$this -> matches = array();
$this -> total_size = new Size(0);
$this -> total_downloads = $this -> total_folders = $this -> total_files = 0;
foreach ($this as $item)
{
if ($item == '..')
{
continue;
}
if (@is_dir($dir . $item))
{
if (stripos($mode, 'd') !== false && self::match($item, $query))
{
$temp = new DirItem($dir, $item);
$this -> matches[] = $temp;
if ($temp -> __get('size') -> __get('bytes') !== false)
{
$this -> total_size -> add_size($temp -> __get('size'));
}
$this -> total_folders++;
}
$sub_search = new Search($query, $dir . $item, $mode);
$this -> merge($sub_search);
}
else if (stripos($mode, 'f') !== false && self::match($item, $query))
{
$temp = new FileItem($dir, $item);
$this -> matches[] = $temp;
$this -> total_size -> add_size($temp -> __get('size'));
$this -> total_downloads += $temp -> __get('downloads');
$this -> total_files++;
}
}
global $words, $config, $subdir;
$link = ' <a class="autoindex_a" href="' . Url::html_output($_SERVER['PHP_SELF'])
. '?dir=' . Url::translate_uri($subdir) . '">'
. Url::html_output($dir) . '</a> ';
$this -> path_nav = $words -> __get('search results for')
. $link . $words -> __get('and its subdirectories');
$this -> contents = $this -> matches;
unset($this -> matches);
}
}
?>

112
classes/Size.php Executable file
View File

@@ -0,0 +1,112 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Represens a filesize. Stored in bytes, and can be formatted as a string.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (July 15, 2004)
* @package AutoIndex
*/
class Size
{
/**
* @var int Size in bytes
*/
private $bytes;
/**
* @return string Returns $bytes formatted as a string
*/
public function formatted()
{
$size = $this -> bytes;
if ($size === true)
//used for the parent directory
{
return '&nbsp;';
}
if ($size === false)
//used for regular directories (if SHOW_DIR_SIZE is false)
{
return '[dir]';
}
static $u = array('&nbsp;B', 'KB', 'MB', 'GB');
for ($i = 0; $size >= 1024 && $i < 4; $i++)
{
$size /= 1024;
}
return number_format($size, 1) . ' ' . $u[$i];
}
/**
* Adds the size of $s into $this
*
* @param Size $s
*/
public function add_size(Size $s)
{
$temp = $s -> __get('bytes');
if (is_int($temp))
{
$this -> bytes += $temp;
}
}
/**
* True if parent directory,
* False if directory,
* Integer for an actual size.
*
* @param mixed $bytes
*/
public function __construct($bytes)
{
$this -> bytes = ((is_bool($bytes)) ? $bytes : max((int)$bytes, 0));
}
/**
* @param string $var The key to look for
* @return string The value $name points to
*/
public function __get($var)
{
if (isset($this -> $var))
{
return $this -> $var;
}
throw new ExceptionDisplay('Variable <em>' . Url::html_output($var)
. '</em> not set in Size class.');
}
}
?>

498
classes/Stats.php Executable file
View File

@@ -0,0 +1,498 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Creates and displays detailed statistics from the log file.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (July 12, 2004)
* @package AutoIndex
*/
class Stats
{
/**
* @var array Stores number of downloads per file extension
*/
private $extensions;
/**
* @var array Hits per day
*/
private $dates;
/**
* @var array Unique hits per day
*/
private $unique_hits;
/**
* @var array Keys are the country codes and values are the number of visits
*/
private $countries;
/**
* @var int Total views of the base_dir
*/
private $total_hits;
/**
* @var int The number of days that there is a log entry for
*/
private $num_days;
/**
* @var int Average hits per day ($total_hits / $num_days)
*/
private $avg;
/**
* Returns $num formatted with a color (green for positive numbers, red
* for negative numbers, and black for 0).
*
* @param int $num
* @return string
*/
private static function get_change_color($num)
{
if ($num > 0)
{
return '<span style="color: #00FF00;">+';
}
if ($num < 0)
{
return '<span style="color: #FF0000;">';
}
return '<span style="color: #000000;">';
}
/**
* If $array[$num] is set, it will be incremented by 1, otherwise it will
* be set to 1.
*
* @param int $num
* @param array $array
*/
private static function add_num_to_array($num, &$array)
{
isset($array[$num]) ? $array[$num]++ : $array[$num] = 1;
}
/**
* Reads the log file, and sets the member variables after doing
* calculations.
*/
public function __construct()
{
$extensions = $dates = $unique_hits = $countries = array();
$total_hits = 0;
global $config;
$log_file = $config -> __get('log_file');
$base_dir = $config -> __get('base_dir');
$h = @fopen($log_file, 'rb');
if ($h === false)
{
throw new ExceptionDisplay("Cannot open log file: <em>$log_file</em>");
}
while (!feof($h))
{
$entries = explode("\t", rtrim(fgets($h, 1024), "\r\n"));
if (count($entries) === 7)
{
//find the number of unique visits
if ($entries[5] == $base_dir)
{
$total_hits++;
if (!in_array($entries[3], $unique_hits))
{
$unique_hits[] = Url::html_output($entries[3]);
}
//find country codes by hostnames
$cc = FileItem::ext($entries[3]);
if (preg_match('/^[a-z]+$/i', $cc))
{
self::add_num_to_array($cc, $countries);
}
//find the dates of the visits
self::add_num_to_array($entries[0], $dates);
}
//find file extensions
$ext = FileItem::ext($entries[6]);
if (preg_match('/^[\w-]+$/', $ext))
{
self::add_num_to_array($ext, $extensions);
}
}
}
fclose($h);
$this -> num_days = count($dates);
$this -> avg = round($total_hits / $this -> num_days);
$this -> extensions = $extensions;
$this -> dates = $dates;
$this -> unique_hits = $unique_hits;
$this -> countries = $countries;
$this -> total_hits = $total_hits;
}
/**
* Uses the display class to output results.
*/
public function display()
{
static $country_codes = array(
'af' => 'Afghanistan',
'al' => 'Albania',
'dz' => 'Algeria',
'as' => 'American Samoa',
'ad' => 'Andorra',
'ao' => 'Angola',
'ai' => 'Anguilla',
'aq' => 'Antarctica',
'ag' => 'Antigua and Barbuda',
'ar' => 'Argentina',
'am' => 'Armenia',
'aw' => 'Aruba',
'au' => 'Australia',
'at' => 'Austria',
'ax' => '&Aring;lang Islands',
'az' => 'Azerbaidjan',
'bs' => 'Bahamas',
'bh' => 'Bahrain',
'bd' => 'Banglades',
'bb' => 'Barbados',
'by' => 'Belarus',
'be' => 'Belgium',
'bz' => 'Belize',
'bj' => 'Benin',
'bm' => 'Bermuda',
'bo' => 'Bolivia',
'ba' => 'Bosnia-Herzegovina',
'bw' => 'Botswana',
'bv' => 'Bouvet Island',
'br' => 'Brazil',
'io' => 'British Indian O. Terr.',
'bn' => 'Brunei Darussalam',
'bg' => 'Bulgaria',
'bf' => 'Burkina Faso',
'bi' => 'Burundi',
'bt' => 'Buthan',
'kh' => 'Cambodia',
'cm' => 'Cameroon',
'ca' => 'Canada',
'cv' => 'Cape Verde',
'ky' => 'Cayman Islands',
'cf' => 'Central African Rep.',
'td' => 'Chad',
'cl' => 'Chile',
'cn' => 'China',
'cx' => 'Christmas Island',
'cc' => 'Cocos (Keeling) Isl.',
'co' => 'Colombia',
'km' => 'Comoros',
'cg' => 'Congo',
'ck' => 'Cook Islands',
'cr' => 'Costa Rica',
'hr' => 'Croatia',
'cu' => 'Cuba',
'cy' => 'Cyprus',
'cz' => 'Czech Republic',
'cs' => 'Czechoslovakia',
'dk' => 'Denmark',
'dj' => 'Djibouti',
'dm' => 'Dominica',
'do' => 'Dominican Republic',
'tp' => 'East Timor',
'ec' => 'Ecuador',
'eg' => 'Egypt',
'sv' => 'El Salvador',
'gq' => 'Equatorial Guinea',
'ee' => 'Estonia',
'et' => 'Ethiopia',
'fk' => 'Falkland Isl. (UK)',
'fo' => 'Faroe Islands',
'fj' => 'Fiji',
'fi' => 'Finland',
'fr' => 'France',
'fx' => 'France (European Terr.)',
'tf' => 'French Southern Terr.',
'ga' => 'Gabon',
'gm' => 'Gambia',
'ge' => 'Georgia',
'de' => 'Germany',
'gh' => 'Ghana',
'gi' => 'Gibraltar',
'gb' => 'Great Britain (UK)',
'gr' => 'Greece',
'gl' => 'Greenland',
'gd' => 'Grenada',
'gp' => 'Guadeloupe (Fr)',
'gu' => 'Guam (US)',
'gt' => 'Guatemala',
'gn' => 'Guinea',
'gw' => 'Guinea Bissau',
'gy' => 'Guyana',
'gf' => 'Guyana (Fr)',
'ht' => 'Haiti',
'hm' => 'Heard &amp; McDonald Isl.',
'hn' => 'Honduras',
'hk' => 'Hong Kong',
'hu' => 'Hungary',
'is' => 'Iceland',
'in' => 'India',
'id' => 'Indonesia',
'ir' => 'Iran',
'iq' => 'Iraq',
'ie' => 'Ireland',
'il' => 'Israel',
'it' => 'Italy',
'ci' => 'Ivory Coast',
'jm' => 'Jamaica',
'jp' => 'Japan',
'jo' => 'Jordan',
'kz' => 'Kazachstan',
'ke' => 'Kenya',
'kg' => 'Kirgistan',
'ki' => 'Kiribati',
'kp' => 'North Korea',
'kr' => 'South Korea',
'kw' => 'Kuwait',
'la' => 'Laos',
'lv' => 'Latvia',
'lb' => 'Lebanon',
'ls' => 'Lesotho',
'lr' => 'Liberia',
'ly' => 'Libya',
'li' => 'Liechtenstein',
'lt' => 'Lithuania',
'lu' => 'Luxembourg',
'mo' => 'Macau',
'mg' => 'Madagascar',
'mw' => 'Malawi',
'my' => 'Malaysia',
'mv' => 'Maldives',
'ml' => 'Mali',
'mt' => 'Malta',
'mh' => 'Marshall Islands',
'mk' => 'Macedonia',
'mq' => 'Martinique (Fr.)',
'mr' => 'Mauritania',
'mu' => 'Mauritius',
'mx' => 'Mexico',
'fm' => 'Micronesia',
'md' => 'Moldavia',
'mc' => 'Monaco',
'mn' => 'Mongolia',
'ms' => 'Montserrat',
'ma' => 'Morocco',
'mz' => 'Mozambique',
'mm' => 'Myanmar',
'na' => 'Namibia',
'nr' => 'Nauru',
'np' => 'Nepal',
'an' => 'Netherland Antilles',
'nl' => 'Netherlands',
'nt' => 'Neutral Zone',
'nc' => 'New Caledonia (Fr.)',
'nz' => 'New Zealand',
'ni' => 'Nicaragua',
'ne' => 'Niger',
'ng' => 'Nigeria',
'nu' => 'Niue',
'nf' => 'Norfolk Island',
'mp' => 'Northern Mariana Isl.',
'no' => 'Norway',
'om' => 'Oman',
'pk' => 'Pakistan',
'pw' => 'Palau',
'pa' => 'Panama',
'pg' => 'Papua New Guinea',
'py' => 'Paraguay',
'pe' => 'Peru',
'ph' => 'Philippines',
'pn' => 'Pitcairn',
'pl' => 'Poland',
'pf' => 'Polynesia (Fr.)',
'pt' => 'Portugal',
'pr' => 'Puerto Rico (US)',
'qa' => 'Qatar',
're' => 'R&eacute;union (Fr.)',
'ro' => 'Romania',
'ru' => 'Russian Federation',
'rw' => 'Rwanda',
'lc' => 'Saint Lucia',
'ws' => 'Samoa',
'sm' => 'San Marino',
'sa' => 'Saudi Arabia',
'sn' => 'Senegal',
'sc' => 'Seychelles',
'sl' => 'Sierra Leone',
'sg' => 'Singapore',
'sk' => 'Slovak Republic',
'si' => 'Slovenia',
'sb' => 'Solomon Islands',
'so' => 'Somalia',
'za' => 'South Africa',
'su' => 'Soviet Union',
'es' => 'Spain',
'lk' => 'Sri Lanka',
'sh' => 'St. Helena',
'pm' => 'St. Pierre &amp; Miquelon',
'st' => 'St. Tome and Principe',
'kn' => 'St. Kitts Nevis Anguilla',
'vc' => 'St. Vincent &amp; Grenadines',
'sd' => 'Sudan',
'sr' => 'Suriname',
'sj' => 'Svalbard &amp; Jan Mayen Isl.',
'sz' => 'Swaziland',
'se' => 'Sweden',
'ch' => 'Switzerland',
'sy' => 'Syria',
'tj' => 'Tadjikistan',
'tw' => 'Taiwan',
'tz' => 'Tanzania',
'th' => 'Thailand',
'tg' => 'Togo',
'tk' => 'Tokelau',
'to' => 'Tonga',
'tt' => 'Trinidad &amp; Tobago',
'tn' => 'Tunisia',
'tr' => 'Turkey',
'tm' => 'Turkmenistan',
'tc' => 'Turks &amp; Caicos Islands',
'tv' => 'Tuvalu',
'ug' => 'Uganda',
'ua' => 'Ukraine',
'ae' => 'United Arab Emirates',
'uk' => 'United Kingdom',
'us' => 'United States',
'uy' => 'Uruguay',
'um' => 'US Minor outlying Isl.',
'uz' => 'Uzbekistan',
'vu' => 'Vanuatu',
'va' => 'Vatican City State',
've' => 'Venezuela',
'vn' => 'Vietnam',
'vg' => 'Virgin Islands (British)',
'vi' => 'Virgin Islands (US)',
'wf' => 'Wallis &amp; Futuna Islands',
'wlk' => 'Wales',
'eh' => 'Western Sahara',
'ye' => 'Yemen',
'yu' => 'Yugoslavia',
'zr' => 'Zaire',
'zm' => 'Zambia',
'zw' => 'Zimbabwe',
'mil' => 'United States Military',
'gov' => 'United States Government',
'com' => 'Commercial',
'net' => 'Network',
'org' => 'Non-Profit Organization',
'edu' => 'Educational',
'int' => 'International',
'aero' => 'Air Transport Industry',
'biz' => 'Businesses',
'coop' => 'Non-profit cooperatives',
'arpa' => 'Arpanet',
'info' => 'Info',
'name' => 'Name',
'nato' => 'Nato',
'museum' => 'Museum',
'pro' => 'Pro'
);
$str = '<table width="40%"><tr><th class="autoindex_th">&nbsp;</th>
<th class="autoindex_th">Total</th><th class="autoindex_th">Daily</th></tr>'
. "<tr class='light_row'><td class='autoindex_td'>Hits</td>
<td class='autoindex_td'>{$this -> total_hits}</td><td class='autoindex_td'>{$this -> avg}"
. '</td></tr><tr class="light_row"><td class="autoindex_td">Unique Hits</td>
<td class="autoindex_td">' . count($this -> unique_hits)
. '</td><td class="autoindex_td">'
. round(count($this -> unique_hits) / $this -> num_days)
. '</td></tr></table><p>Percent Unique: '
. number_format(count($this -> unique_hits) / $this -> total_hits * 100, 1) . '</p>';
arsort($this -> extensions);
arsort($this -> countries);
$date_nums = array_values($this -> dates);
$str .= '<table width="75%" border="0"><tr><th class="autoindex_th">Date</th>
<th class="autoindex_th">Hits That Day</th><th class="autoindex_th">Change From Previous Day</th>
<th class="autoindex_th">Difference From Average (' . $this -> avg
. ')</th></tr>';
$i = 0;
foreach ($this -> dates as $day => $num)
{
$diff = $num - $this -> avg;
$change = (($i > 0) ? ($num - $date_nums[$i-1]) : 0);
$change_color = self::get_change_color($change);
$diff_color = self::get_change_color($diff);
$class = (($i++ % 2) ? 'dark_row' : 'light_row');
$str .= "<tr class='$class'><td class='autoindex_td'>$day</td>
<td class='autoindex_td'>$num</td>
<td class='autoindex_td'>$change_color$change</span></td>
<td class='autoindex_td'>$diff_color$diff</span></td></tr>";
}
$str .= '</table><p /><table width="75%" border="0">
<tr><th class="autoindex_th">Downloads based on file extensions</th>
<th class="autoindex_th">Total</th><th class="autoindex_th">Daily</th></tr>';
$i = 0;
foreach ($this -> extensions as $ext => $num)
{
$class = (($i++ % 2) ? 'dark_row' : 'light_row');
$str .= "<tr class='$class'><td class='autoindex_td'>$ext</td>
<td class='autoindex_td'>$num</td><td class='autoindex_td'>"
. number_format($num / $this -> num_days, 1) . "</td></tr>";
}
$str .= '</table><p /><table width="75%" border="0"><tr>
<th class="autoindex_th">Hostname ISP extension</th>
<th class="autoindex_th">Total</th><th class="autoindex_th">Daily</th></tr>';
$i = 0;
foreach ($this -> countries as $c => $num)
{
$c_code = (isset($country_codes[strtolower($c)]) ? ' <span class="autoindex_small">('
. $country_codes[strtolower($c)] . ')</span>' : '');
$class = (($i++ % 2) ? 'dark_row' : 'light_row');
$str .= "<tr class='$class'><td class='autoindex_td'>$c{$c_code}</td><td class='autoindex_td'>$num</td><td class='autoindex_td'>"
. number_format($num / $this -> num_days, 1) . "</td></tr>\n";
}
$str .= '</table><p><a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']) . '">Continue.</a></p>';
echo new Display($str);
die();
}
}
?>

128
classes/Tar.php Executable file
View File

@@ -0,0 +1,128 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Creates and outputs a tar archive given an array of filenames.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (July 03, 2004)
* @package AutoIndex
*/
class Tar
{
/**
* @var int Length of directory path to cut off from start
*/
private $base_dir_length;
/**
* @var string Added in the filepath inside the tar archive
*/
private $prepend_path;
/**
* @param string $data
* @return int The checksum of $data
*/
private static function checksum(&$data)
{
$unsigned_chksum = 0;
for ($i = 0; $i < 512; $i++)
{
$unsigned_chksum += ord($data{$i});
}
for ($i = 148; $i < 156; $i++)
{
$unsigned_chksum -= ord($data{$i});
}
return $unsigned_chksum + 256;
}
/**
* @param string $name The file or folder name
* @param int $size The size of the file (0 for directories)
* @param bool $is_dir True if folder, false if file
*/
private function create_header($name, $size = 0, $is_dir = true)
{
$header = str_pad($this -> prepend_path . substr($name, $this -> base_dir_length), 100, "\0") //filename
. str_pad('755', 7, '0', STR_PAD_LEFT) . "\0" //permissions
. '0000000' . "\0" //uid
. '0000000' . "\0" //gid
. str_pad(decoct($size), 11, '0', STR_PAD_LEFT) . "\0" //size
. str_pad(decoct(filemtime($name)), 11, '0', STR_PAD_LEFT) . "\0" //time
. ' ' //checksum (8 spaces)
. ($is_dir ? '5' : '0') //typeflag
. str_repeat("\0", 100) //linkname
. 'ustar ' //magic
/*
* version (1) + username (32) + groupname (32) + devmajor (8) +
* devminor (8) + prefix (155) + end (12) = 248
*/
. str_repeat("\0", 248);
$checksum = str_pad(decoct(self::checksum($header)), 6, '0', STR_PAD_LEFT) . "\0 ";
return substr_replace($header, $checksum, 148, strlen($checksum));
}
/**
* @param DirectoryList $filenames List of files to add to the archive
* @param string $prepend_path Added in the filepath inside the tar archive
* @param int $base_dir_length Length of directory path to cut off from start
*/
public function __construct(DirectoryList $filenames, $prepend_path = '', $base_dir_length = 0)
{
$this -> base_dir_length = (int)$base_dir_length;
$this -> prepend_path = Item::make_sure_slash($prepend_path);
foreach ($filenames as $base)
{
$name = $filenames -> __get('dir_name') . $base;
if (@is_dir($name))
{
if ($base != '.' && $base != '..')
{
echo $this -> create_header($name);
$list = new DirectoryList($name);
new Tar($list, $this -> prepend_path, $this -> base_dir_length);
}
}
else if (@is_file($name) && @is_readable($name) && ($size = @filesize($name)))
{
echo $this -> create_header($name, $size, false);
Url::force_download($name, false);
echo str_repeat("\0", (ceil($size / 512) * 512) - $size);
}
}
}
}
?>

146
classes/Template.php Executable file
View File

@@ -0,0 +1,146 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2005 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Reads the file contents, then parses comments and translated words.
*
* First step in parsing a template file. Used on all templates:
* - global header
* - global footer
* - table header
* - table footer
* - each_file
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.3 (February 02, 2005)
* @package AutoIndex
*/
class Template
{
/**
* @var string The final output
*/
protected $out;
/**
* @param array $m The array given by preg_replace_callback()
* @return string Looks up $m[1] in word list and returns match
*/
private static function callback_words($m)
{
global $words;
return $words -> __get(strtolower($m[1]));
}
/**
* @param array $m The array given by preg_replace_callback()
* @return string The parsed template of filename $m[1]
*/
private static function callback_include($m)
{
$temp = new Template($m[1]);
return $temp -> __toString();
}
/**
* @param array $m The array given by preg_replace_callback()
* @return string The setting for the config value $m[1]
*/
private static function callback_config($m)
{
global $config;
return $config -> __get(strtolower($m[1]));
}
/**
* Parses the text in $filename and sets the result to $out. We cannot
* use ExceptionDisplay here if there is an error, since it uses the
* template system.
*
* Steps to parse the template:
* - remove comments
* - replace {info} variables
* - replace {words} strings
* - replace {config} variables
* - include other files when we see the {include} statement
*
* @param string $filename The name of the file to parse
*/
public function __construct($filename)
{
global $config, $dir, $subdir;
$full_filename = $config -> __get('template') . $filename;
if (!@is_file($full_filename))
{
throw new ExceptionFatal('Template file <em>'
. Url::html_output($full_filename) . '</em> cannot be found.');
}
//read raw file contents
$contents = @file_get_contents($full_filename);
if ($contents === false)
{
throw new ExceptionFatal('Template file <em>'
. Url::html_output($full_filename) . '</em> could not be opened for reading.');
}
//remove comments
$contents = preg_replace('#/\*.*?\*/#s', '', $contents);
//replace info variables and word strings from language file
$tr = array(
'{info:dir}' => (isset($dir) ? Url::html_output($dir) : ''),
'{info:subdir}' => (isset($subdir) ? Url::html_output($subdir) : ''),
'{info:version}' => VERSION,
'{info:page_time}' => round((microtime(true) - START_TIME) * 1000, 1));
$contents = preg_replace_callback('/\{\s*words?\s*:\s*(.+)\s*\}/Ui',
array('self', 'callback_words'), strtr($contents, $tr));
//replace {config} variables
$contents = preg_replace_callback('/\{\s*config\s*:\s*(.+)\s*\}/Ui',
array('self', 'callback_config'), $contents);
//parse includes
$this -> out = preg_replace_callback('/\{\s*include\s*:\s*(.+)\s*\}/Ui',
array('self', 'callback_include'), $contents);
}
/**
* @return string The HTML text of the parsed template
*/
public function __toString()
{
return $this -> out;
}
}
?>

244
classes/TemplateFiles.php Executable file
View File

@@ -0,0 +1,244 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* In addition to everything TemplateInfo and template parse, this adds
* information about files/folders through the item class.
*
* Third and final step for parsing templates. Only used for:
* - each_file
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (July 09, 2004)
* @package AutoIndex
*/
class TemplateFiles extends TemplateInfo
{
/**
* @var Item The file or folder we're currently processing
*/
private $temp_item;
/**
* @var bool Is the current user an admin
*/
private $is_admin;
/**
* @var bool Is the current user a moderator
*/
private $is_mod;
/**
* @var int The number of the file we're currently processing
*/
private $i;
/**
* @var int The total number of files to process
*/
private $length;
/**
* @param array $m The array given by preg_replace_callback()
* @return string Property is gotten from temp_item
*/
private function callback_file($m)
{
global $words, $subdir;
switch (strtolower($m[1]))
{
case 'tr_class':
{
return (($this -> i % 2) ? 'dark_row' : 'light_row');
}
case 'filename':
{
return Url::html_output($this -> temp_item -> __get('filename'));
}
case 'file_ext':
{
return $this -> temp_item -> file_ext();
}
case 'size':
{
return $this -> temp_item -> __get('size') -> formatted();
}
case 'bytes':
{
return $this -> temp_item -> __get('size') -> __get('bytes');
}
case 'date':
case 'time':
case 'm_time':
{
return $this -> temp_item -> format_m_time();
}
case 'a_time':
{
return $this -> temp_item -> format_a_time();
}
case 'thumbnail':
{
return $this -> temp_item -> __get('thumb_link');
}
case 'num_subfiles':
{
return (($this -> temp_item instanceof DirItem
&& !$this -> temp_item -> __get('is_parent_dir')) ? $this -> temp_item -> num_subfiles() : '');
}
case 'delete_link':
{
return (($this -> is_admin && !$this -> temp_item -> __get('is_parent_dir')) ?
' [<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=delete&amp;dir=' . rawurlencode($subdir)
. '&amp;filename=' . rawurlencode($this -> temp_item -> __get('filename'))
. '" class="autoindex_small autoindex_a">' . $words -> __get('delete') . '</a>]' : '');
}
case 'rename_link':
{
return (($this -> is_admin && !$this -> temp_item -> __get('is_parent_dir')) ?
' [<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=rename&amp;dir=' . rawurlencode($subdir)
. '&amp;filename=' . rawurlencode($this -> temp_item -> __get('filename'))
. '" class="autoindex_small autoindex_a">' . $words -> __get('rename') . '</a>]' : '');
}
case 'edit_description_link':
{
$slash = (($this -> temp_item instanceof DirItem) ? '/' : '');
return (($this -> is_mod && DESCRIPTION_FILE && !$this -> temp_item -> __get('is_parent_dir')) ?
' [<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=edit_description&amp;dir='
. rawurlencode($subdir) . '&amp;filename='
. rawurlencode($this -> temp_item -> __get('filename')) . $slash
. '" class="autoindex_small autoindex_a">'
. $words -> __get('edit description') . '</a>]' : '');
}
case 'ftp_upload_link':
{
if (!$this -> is_mod || !$this -> temp_item instanceof FileItem || !isset($_SESSION['ftp']))
{
return '';
}
return ' [<a href="' . Url::html_output($_SERVER['PHP_SELF']) . '?action=ftp&amp;dir='
. rawurlencode($subdir) . '&amp;filename=' . rawurlencode($this -> temp_item -> __get('filename'))
. '" class="autoindex_small autoindex_a">' . $words->__get('upload to ftp') . '</a>]';
}
default:
{
return $this -> temp_item -> __get($m[1]);
}
}
}
/**
* Either the HTML text is returned, or an empty string is returned,
* depending on if the if-statement passed.
*
* @param array $m The array given by preg_replace_callback()
* @return string The result to insert into the HTML
*/
private function callback_type($m)
{
switch (strtolower($m[1]))
{
case 'is_file': //file
{
return (($this -> temp_item instanceof FileItem) ? $m[2] : '');
}
case 'is_dir': //folder or link to parent directory
{
return (($this -> temp_item instanceof DirItem) ? $m[2] : '');
}
case 'is_real_dir': //folder
{
return (($this -> temp_item instanceof DirItem
&& !$this -> temp_item -> __get('is_parent_dir')) ? $m[2] : '');
}
case 'is_parent_dir': //link to parent directory
{
return (($this -> temp_item instanceof DirItem
&& $this -> temp_item -> __get('is_parent_dir')) ? $m[2] : '');
}
default:
{
throw new ExceptionDisplay('Invalid file:if statement in <em>'
. Url::html_output(EACH_FILE) . '</em>');
}
}
}
/**
* Either the HTML text is returned or an empty string is returned,
* depending on if temp_item is the ith file parsed.
*
* @param array $m The array given by preg_replace_callback()
* @return string The result to insert into the HTML output
*/
private function callback_do_every($m)
{
$num = $this -> i + 1;
return (($num % (int)$m[1] === 0 && $this -> length !== $num) ? $m[2] : '');
}
/**
* Parses info for each file in the directory. Order of elements to
* replace is:
* - file:if
* - do_every
* - file
*
* @param string $filename The name of the file to parse
* @param DirectoryListDetailed $list
*/
public function __construct($filename, DirectoryListDetailed $list)
{
parent::__construct($filename, $list);
global $you;
$this -> is_admin = ($you -> level >= ADMIN);
$this -> is_mod = ($you -> level >= MODERATOR);
$final_file_line = '';
$this -> length = (int)$list -> __get('list_count');
foreach ($list as $i => $item)
{
$this -> i = (int)$i;
$this -> temp_item = $item;
$temp_line = preg_replace_callback('/\{\s*file\s*:\s*if\s*:\s*(\w+)\s*\}(.*)\{\s*end\s*if\s*\}/Uis',
array($this, 'callback_type'), $this -> out);
$temp_line = preg_replace_callback('/\{\s*do_every\s*:\s*(\d+)\s*\}(.*)\{\s*end\s*do_every\s*\}/Uis',
array($this, 'callback_do_every'), $temp_line);
$final_file_line .= preg_replace_callback('/\{\s*file\s*:\s*(\w+)\s*\}/Ui',
array($this, 'callback_file'), $temp_line);
}
$this -> out = $final_file_line;
}
}
?>

205
classes/TemplateInfo.php Executable file
View File

@@ -0,0 +1,205 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2006 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* In addition to everything the template class parses, this parses if
* statements and information about the current working directory.
*
* Second step in parsing templates. Used for:
* - global header
* - global footer
* - table header
* - table footer
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.1.0 (January 01, 2006)
* @package AutoIndex
*/
class TemplateInfo extends Template
{
/**
* @var DirectoryListDetailed
*/
private $dir_list;
/**
* @param array $m The array given by preg_replace_callback()
* @return string Link to change the sort mode
*/
private static function callback_sort($m)
{
global $subdir;
$m = Url::html_output(strtolower($m[1]));
$temp = Url::html_output($_SERVER['PHP_SELF']) . '?dir=' . $subdir
. '&amp;sort=' . $m . '&amp;sort_mode='
. (($_SESSION['sort'] == $m && $_SESSION['sort_mode'] == 'a') ? 'd' : 'a');
if (isset($_GET['search'], $_GET['search_mode'])
&& $_GET['search'] != '' && $_GET['search_mode'] != '')
{
$temp .= '&amp;search=' . Url::html_output($_GET['search'])
. '&amp;search_mode=' . Url::html_output($_GET['search_mode']);
}
return $temp;
}
/**
* @param array $m The array given by preg_replace_callback()
* @return string Property is gotten from dir_list
*/
private function callback_info($m)
{
switch (strtolower($m[1]))
{
case 'archive_link':
{
global $config;
return Url::html_output($_SERVER['PHP_SELF']) . '?archive=true&amp;dir='
. substr($this -> dir_list -> __get('dir_name'), strlen($config -> __get('base_dir')));
}
case 'total_size':
{
return $this -> dir_list -> __get('total_size') -> formatted();
}
case 'search_box':
{
return Search::search_box();
}
case 'login_box':
{
global $you;
return $you -> login_box();
}
case 'current_page_number':
{
if (!ENTRIES_PER_PAGE)
{
return 1;
}
global $page;
return $page;
}
case 'last_page_number':
{
if (!ENTRIES_PER_PAGE)
{
return 1;
}
global $max_page;
return $max_page;
}
case 'previous_page_link':
{
if (!ENTRIES_PER_PAGE)
{
return '';
}
global $config, $page;
if ($page <= 1)
{
return '&lt;&lt;';
}
return '<a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']) . '?page=' . ($page - 1)
. '&amp;dir=' . substr($this -> dir_list -> __get('dir_name'),
strlen($config -> __get('base_dir'))) . '">&lt;&lt;</a>';
}
case 'next_page_link':
{
if (!ENTRIES_PER_PAGE)
{
return '';
}
global $config, $page, $max_page;
if ($page >= $max_page)
{
return '&gt;&gt;';
}
return '<a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']) . '?page=' . ($page + 1)
. '&amp;dir=' . substr($this -> dir_list -> __get('dir_name'),
strlen($config -> __get('base_dir'))) . '">&gt;&gt;</a>';
}
default:
{
return $this -> dir_list -> __get($m[1]);
}
}
}
/**
* Either the HTML text is returned, or an empty string is returned,
* depending on if the if-statement passed.
*
* @param array $m The array given by preg_replace_callback()
* @return string The result to insert into the HTML
*/
private static function callback_if($m)
{
$var = strtoupper($m[1]);
if (!defined($var))
{
throw new ExceptionDisplay('<em>$' . Url::html_output($m[1])
. '</em> is not a valid variable (check if-statement in template file).');
}
return (constant($var) ? $m[2] : '');
}
/**
* @param string $filename The name of the file to parse
* @param DirectoryListDetailed $dir_list
*/
public function __construct($filename, DirectoryListDetailed $dir_list)
{
parent::__construct($filename);
$this -> dir_list = $dir_list;
//parse if-statements
$last_text = '';
$regex = '/\{\s*if\s*:\s*(\w+)\s*\}(.*)\{\s*end\s*if\s*:\s*\1\s*\}/Uis'; //match {if:foo} ... {end if:foo}
while ($last_text != ($this -> out = preg_replace_callback($regex, array('self', 'callback_if'), $this -> out)))
{
$last_text = $this -> out;
}
$this -> out = $last_text;
//parse sort modes
$this -> out = preg_replace_callback('/\{\s*sort\s*:\s*(\w+)\s*\}/Ui',
array('self', 'callback_sort'), $this -> out);
//replace {info} variables
$this -> out = preg_replace_callback('/\{\s*info\s*:\s*(\w+)\s*\}/Ui',
array($this, 'callback_info'), $this -> out);
}
}
?>

153
classes/Upload.php Executable file
View File

@@ -0,0 +1,153 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Allows files to be uploaded to the server from people's computers. By
* default, only users logged in with level USER or higher may upload files.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (June 30, 2004)
* @package AutoIndex
*/
class Upload
{
/**
* Uploads all files in the $_FILES array, then echos the results.
*/
public function do_upload()
{
$uploaded_files = $errors = '';
global $words, $log, $dir;
foreach ($_FILES as $file_upload)
{
$filename = Item::get_basename($file_upload['name']);
if ($filename == '')
{
continue;
}
if (DirectoryList::is_hidden($filename))
{
$errors .= "<li>$filename ["
. $words -> __get('filename is listed as a hidden file')
. ']</li>';
continue;
}
$filename = Url::clean_input($filename);
$fullpathname = realpath($dir) . '/' . $filename;
if (@file_exists($fullpathname))
{
$errors .= "<li>$filename ["
. $words -> __get('file already exists') . ']</li>';
}
else if (@move_uploaded_file($file_upload['tmp_name'], $fullpathname))
{
@chmod($fullpathname, 0644);
$uploaded_files .= "<li>$filename</li>";
$log -> add_entry("Uploaded file: $filename");
}
else
{
$errors .= "<li>$filename</li>";
}
}
if ($errors == '')
{
$errors = '<br />[' . $words -> __get('none') . ']';
}
if ($uploaded_files == '')
{
$uploaded_files = '<br />[' . $words -> __get('none') . ']';
}
$str = '<table><tr class="paragraph"><td class="autoindex_td" style="padding: 8px;">'
. '<strong>' . $words -> __get('uploaded files')
. "</strong>: $uploaded_files</p><p><strong>"
. $words -> __get('failed files') . "</strong>: $errors"
. '<p><a class="autoindex_a" href="' . Url::html_output($_SERVER['PHP_SELF']);
if (isset($_GET['dir']))
{
$str .= '?dir=' . Url::translate_uri($_GET['dir']);
}
$str .= '">' . $words -> __get('continue') . '.</a></p></td></tr></table>';
echo new Display($str);
die();
}
/**
* @param User $current_user Makes sure the user has permission to upload files
*/
public function __construct(User $current_user)
{
if ($current_user -> level < LEVEL_TO_UPLOAD)
{
throw new ExceptionDisplay('Your user account does not have permission to upload files.');
}
}
/**
* @return string The HTML that makes up the upload form
*/
public function __toString()
{
global $words, $subdir;
if (isset($_GET['num_uploads']) && (int)$_GET['num_uploads'] > 0)
{
$str = '<form enctype="multipart/form-data" action="'
. Url::html_output($_SERVER['PHP_SELF']) . '?dir=' . $subdir . '" method="post"><p>';
$num = min((int)$_GET['num_uploads'], 100);
for ($i = 0; $i < $num; $i++)
{
$str .= "\n\t" . $words -> __get('file')
. ' '. ($i + 1) . ' : <input name="' . $i
. '" type="file" /><br />';
}
$str .= '</p><p><input type="submit" value="'
. $words -> __get('upload') . '" /></p></form>';
$str = '<table><tr class="paragraph"><td class="autoindex_td" style="padding: 8px;">'
. $str . '<p><a class="autoindex_a" href="'
. Url::html_output($_SERVER['PHP_SELF']);
if (isset($_GET['dir']))
{
$str .= '?dir=' . Url::translate_uri($_GET['dir']);
}
$str .= '">' . $words -> __get('continue') . '.</a></p></td></tr></table>';
echo new Display($str);
die();
}
return '<form action="' . Url::html_output($_SERVER['PHP_SELF']) . '" method="get"><p>'
. $words -> __get('upload') . ' <input type="text" size="3" value="1" name="num_uploads" /> '
. $words -> __get('files to this folder') . '<input class="button" type="submit" value="'
. $words -> __get('upload') . '" /><input type="hidden" name="dir" value="'
. $subdir . '" /></p></form>';
}
}
?>

232
classes/Url.php Executable file
View File

@@ -0,0 +1,232 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Represents URLs. Deals with special characters and redirection/downloading.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.4 (November 9, 2007)
* @package AutoIndex
*/
class Url
{
/**
* @var string
*/
private $url;
/**
* Rawurlencodes $uri, but not slashes.
*
* @param string $uri
* @return string
*/
public static function translate_uri($uri)
{
$uri = rawurlencode(str_replace('\\', '/', $uri));
return str_replace(rawurlencode('/'), '/', $uri);
}
/**
* Returns the string with correct HTML entities so it can be displayed.
*
* @param string $str
* @return string
*/
public static function html_output($str)
{
return htmlentities($str, ENT_QUOTES, 'UTF-8');
}
/**
* Checks input for hidden files/folders, and deals with ".."
*
* @param string $d The URL to check
* @return string Safe version of $d
*/
private static function eval_dir($d)
{
$d = str_replace('\\', '/', $d);
if ($d == '' || $d == '/')
{
return '';
}
$dirs = explode('/', $d);
for ($i = 0; $i < count($dirs); $i++)
{
if (DirectoryList::is_hidden($dirs[$i], false))
{
array_splice($dirs, $i, 1);
$i--;
}
else if (preg_match('/^\.\./', $dirs[$i])) //if it starts with two dots
{
array_splice($dirs, $i-1, 2);
$i = -1;
}
}
$new_dir = implode('/', $dirs);
if ($new_dir == '' || $new_dir == '/')
{
return '';
}
if ($d{0} == '/' && $new_dir{0} != '/')
{
$new_dir = '/' . $new_dir;
}
if (preg_match('#/$#', $d) && !preg_match('#/$#', $new_dir))
{
$new_dir .= '/';
}
else if (DirectoryList::is_hidden(Item::get_basename($new_dir)))
//it's a file, so make sure the file itself is not hidden
{
return DirItem::get_parent_dir($new_dir);
}
return $new_dir;
}
/**
* @param string $url The URL path to check and clean
* @return string Resolves $url's special chars and runs eval_dir on it
*/
public static function clean_input($url)
{
$url = rawurldecode( $url );
$newURL = '';
for ( $i = 0; $i < strlen( $url ); $i++ ) //loop to remove all null chars
{
if ( ord($url[$i]) != 0 )
{
$newURL .= $url[$i];
}
}
return self::eval_dir( $newURL );
}
/**
* Sends the browser a header to redirect it to this URL.
*/
public function redirect()
{
$site = $this -> url;
header("Location: $site");
die(simple_display('Redirection header could not be sent.<br />'
. "Continue here: <a href=\"$site\">$site</a>"));
}
/**
* @param string $file_dl
* @param bool $headers
*/
public static function force_download($file_dl, $headers = true)
{
if (!@is_file($file_dl))
{
header('HTTP/1.0 404 Not Found');
throw new ExceptionDisplay('The file <em>'
. self::html_output($file_dl)
. '</em> could not be found on this server.');
}
if (!($fn = @fopen($file_dl, 'rb')))
{
throw new ExceptionDisplay('<h3>Error 401: permission denied</h3> you cannot access <em>'
. Url::html_output($file_dl) . '</em> on this server.');
}
if ($headers)
{
$outname = Item::get_basename($file_dl);
$size = @filesize($file_dl);
if ($size !== false)
{
header('Content-Length: ' . $size);
}
$mime = new MimeType($outname);
header('Content-Type: ' . $mime -> __toString() . '; name="' . $outname . '"');
header('Content-Disposition: attachment; filename="' . $outname . '"');
}
global $speed;
while (true)
{
$temp = @fread($fn, (int)($speed * 1024));
if ($temp === '')
{
break;
}
echo $temp;
flush();
if (BANDWIDTH_LIMIT)
{
sleep(1);
}
}
fclose($fn);
}
/**
* Downloads the URL on the user's browser, using either the redirect()
* or force_download() functions.
*/
public function download()
{
if (FORCE_DOWNLOAD)
{
@set_time_limit(0);
self::force_download(self::clean_input($this -> url));
die();
}
$this -> redirect();
}
/**
* @param string $text_url The URL to create an object from
* @param bool $special_chars If true, translate_uri will be run on the url
*/
public function __construct($text_url, $special_chars = false)
{
if ($special_chars)
{
$text_url = self::translate_uri($text_url);
}
$this -> url = $text_url;
}
/**
* @return string Returns the URL as a string
*/
public function __toString()
{
return $this -> url;
}
}
?>

152
classes/User.php Executable file
View File

@@ -0,0 +1,152 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Stores info about an individual user account, such as username and password.
*
* This class is basically just used for storing data (hence all variables are
* public). Currently, each user has four properties: username, password,
* level, and home directory.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (July 21, 2004)
* @package AutoIndex
*/
class User
{
/**
* @var string Username
*/
public $username;
/**
* @var string The password, stored as a sha-1 hash of the actual password
*/
public $sha1_pass;
/**
* @var int The user's level (use the GUEST USER ADMIN constants)
*/
public $level;
/**
* @var string The user's home directory, or an empty string to use the default base_dir
*/
public $home_dir;
/**
* @param User $user The user to compare to $this
* @return bool True if this user is equal to $user, based on username and password
*/
public function equals(User $user)
{
return ((strcasecmp($this -> username, $user -> username) === 0)
&& (strcasecmp($this -> sha1_pass, $user -> sha1_pass) === 0));
}
/**
* Since this is not an instance of UserLoggedIn, we know he is not
* logged in.
*/
public function logout()
{
throw new ExceptionDisplay('You are not logged in.');
}
/**
* Here we display a login box rather than account options, since this is
* not an instance of UserLoggedIn.
*
* @return string The HTML text of the login box
*/
public function login_box()
{
$str = '';
if (USE_LOGIN_SYSTEM)
{
global $words, $subdir;
$str .= '<form action="' . Url::html_output($_SERVER['PHP_SELF']) . '?dir='
. (isset($subdir) ? rawurlencode($subdir) : '')
. '" method="post"><table><tr class="paragraph"><td>'
. $words -> __get('username') . ':</td><td><input type="text" name="username" />'
. '</td></tr><tr class="paragraph"><td>' . $words -> __get('password')
. ':</td><td><input type="password" name="password" /></td></tr></table>'
. '<p><input class="button" type="submit" value="'
. $words -> __get('login') . '" /></p></form>';
}
if (LEVEL_TO_UPLOAD === GUEST)
{
global $you;
$upload_panel = new Upload($you);
$str .= $upload_panel -> __toString();
}
return $str;
}
/**
* @param string $username Username
* @param string $sha1_pass Password as a sha-1 hash
* @param int $level User's level (use the GUEST, USER, MODERATOR, ADMIN constants)
* @param string $home_dir The home directory of the user, or blank for the default
*/
public function __construct($username = '', $sha1_pass = '', $level = GUEST, $home_dir = '')
{
$level = (int)$level;
if ($level < BANNED || $level > ADMIN)
{
throw new ExceptionDisplay('Error in user accounts file:
Invalid user level (for username "'
. Url::html_output($username) . '").');
}
if ($sha1_pass != '' && strlen($sha1_pass) !== 40)
{
throw new ExceptionDisplay('Error in user accounts file:
Invalid password hash (for username "'
. Url::html_output($username) . '").');
}
$this -> sha1_pass = $sha1_pass;
$this -> username = $username;
$this -> level = $level;
$this -> home_dir = $home_dir;
}
/**
* @return string This string format is how it is stored in the user_list file
*/
public function __toString()
{
return $this -> username . "\t" . $this -> sha1_pass . "\t"
. $this -> level . "\t" . $this -> home_dir . "\n";
}
}
?>

114
classes/UserLoggedIn.php Executable file
View File

@@ -0,0 +1,114 @@
<?php
/**
* @package AutoIndex
*
* @copyright Copyright (C) 2002-2004 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
/**
* Represents a user that is currently logged in.
*
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.0.1 (July 02, 2004)
* @package AutoIndex
*/
class UserLoggedIn extends User
{
/**
* Since the user is already logged in, the account options will be
* displayed rather than a login box.
*
* @return string The HTML text that makes up the account options box
*/
public function login_box()
{
global $words, $you, $subdir;
$txt = '<p><a class="autoindex_a" href="' . Url::html_output($_SERVER['PHP_SELF'])
. '?dir=' . (isset($subdir) ? rawurlencode($subdir) : '')
. '&amp;logout=true">' . $words -> __get('logout')
. ' [ ' . Url::html_output($this -> username) . ' ]</a></p>';
if ($you -> level >= MODERATOR)
//show admin options if they are a moderator or higher
{
$admin_panel = new Admin($you);
$txt = $admin_panel -> __toString() . $txt;
}
if ($you -> level >= LEVEL_TO_UPLOAD)
//show upload options if they are a logged in user or higher
{
$upload_panel = new Upload($you);
$txt .= $upload_panel -> __toString();
}
return $txt;
}
/**
* Logs out the user by destroying the session data and refreshing the
* page.
*/
public function logout()
{
global $subdir;
$this -> level = GUEST;
$this -> sha1_pass = $this -> username = '';
session_unset();
session_destroy();
$home = new Url(Url::html_output($_SERVER['PHP_SELF']), true);
$home -> redirect();
}
/**
* Validates username and password using the accounts stored in the
* user_list file.
*
* @param string $username The username to login
* @param string $sha1_pass The sha-1 hash of the password
*/
public function __construct($username, $sha1_pass)
{
parent::__construct($username, $sha1_pass);
$accounts = new Accounts();
if (!($accounts -> is_valid_user($this)))
{
global $log;
$log -> add_entry("Invalid login (Username: $username)");
session_unset();
sleep(1);
throw new ExceptionDisplay('Invalid username or password.');
}
$this -> level = $accounts -> get_level($username);
if ($this -> level <= BANNED)
{
throw new ExceptionDisplay('Your account has been disabled by the site admin.');
}
$this -> username = $accounts -> get_stored_case($username);
$this -> home_dir = $accounts -> get_home_dir($username);
}
}
?>

539
config.php Executable file
View File

@@ -0,0 +1,539 @@
<?php
/**
* When a file with the stored config data is not present, this file is
* automatically included to create a new one.
*
* @package AutoIndex
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.2.0 (January 01, 2006)
*
* @copyright Copyright (C) 2002-2006 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
if (!defined('IN_AUTOINDEX') || !IN_AUTOINDEX)
{
die();
}
$strings = array('base_dir', 'icon_path', 'language', 'template', 'log_file',
'description_file', 'user_list', 'download_count', 'hidden_files',
'banned_list');
$checkboxes = array('show_dir_size', 'use_login_system', 'force_download',
'search_enabled', 'anti_leech', 'must_login_to_download', 'archive',
'parse_htaccess');
$numbers = array('days_new', 'thumbnail_height', 'bandwidth_limit', 'md5_show',
'entries_per_page');
if (count($_POST) >= count($strings) + count($numbers))
{
$directories = array('base_dir', 'icon_path', 'template');
$output = "<?php\n\n/* AutoIndex PHP Script config file\n\n";
foreach ($strings as $setting)
{
if (!isset($_POST[$setting]))
{
die(simple_display('Required setting <em>'
. htmlentities($setting) . '</em> not set.'));
}
if ($_POST[$setting] == '')
{
$output .= "$setting\tfalse\n";
continue;
}
$_POST[$setting] = str_replace('\\', '/', $_POST[$setting]);
if (in_array($setting, $directories) && !preg_match('#/$#', $_POST[$setting]))
//make sure there is a slash at the end of directories
{
$_POST[$setting] .= '/';
}
$output .= "$setting\t{$_POST[$setting]}\n";
}
foreach ($checkboxes as $setting)
{
$output .= "$setting\t" . (isset($_POST[$setting]) ? 'true' : 'false')
. "\n";
}
foreach ($numbers as $setting)
{
if (!isset($_POST[$setting]))
{
die(simple_display('Required setting <em>'
. htmlentities($setting) . '</em> not set.'));
}
if ($_POST[$setting] == '')
{
$output .= "$setting\t0\n";
continue;
}
if ($_POST[$setting] < 0)
{
die(simple_display('The setting <em>'
. htmlentities($setting) . '</em> should not be a negitive number.'));
}
$_POST[$setting] = (string)((float)$_POST[$setting]);
$output .= "$setting\t{$_POST[$setting]}\n";
}
$output .= "\n*/\n\n?>";
if (!isset($_POST['force_download']))
{
if (preg_match('#^(/|[a-z]\:)#i', $_POST['base_dir']))
{
die(simple_display('It seems you are using an absolute path for the Base Directory.'
. '<br />This means you must check the "Pipe downloaded files though the PHP script" box.'));
}
if ((int)$_POST['bandwidth_limit'] !== 0)
{
die(simple_display('For the Bandwidth Limit feature to work, the "force download" feature needs to be on.'
. '<br />This means you must check the "Pipe downloaded files though the PHP script" box.'));
}
}
if (isset($_POST['must_login_to_download']) && !isset($_POST['use_login_system']))
{
die(simple_display('To enable <em>must_login_to_download</em>, the '
. '<em>use_login_system</em> option must also be turned on.'));
}
foreach (array('base_dir', 'template') as $valid)
{
if (!@is_dir($_POST[$valid]))
{
die(simple_display(htmlentities($valid)
. ' setting is not a valid directory.'));
}
}
if (@is_file(CONFIG_STORED))
//if the file already exists, back it up
{
$temp_name = CONFIG_STORED . '.bak';
for ($i = 1; @file_exists($temp_name); $i++)
{
$temp_name = CONFIG_STORED . '.bak' . (string)$i;
}
@copy(CONFIG_STORED, $temp_name);
}
$h = @fopen(CONFIG_STORED, 'wb');
if ($h === false)
//the file could not be written to, so now it must be downloaded through the browser
{
header('Content-Type: text/plain; name="' . CONFIG_STORED . '"');
header('Content-Disposition: attachment; filename="' . CONFIG_STORED . '"');
die($output);
}
else
//the file was opened successfully, so write to it
{
fwrite($h, $output);
fclose($h);
//begin display of "configuration complete" page
echo '<?xml version="1.0" encoding="iso-8859-1"?>';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>AutoIndex Configuration: Complete!</title>
<style type="text/css" title="AutoIndex Default">
html, body
{
background-color: #F0F0F0;
color: #000020;
font-family: verdana, lucidia, sans-serif;
font-size: 15px;
}
a:visited, a:active
{
color: #00008F;
text-decoration: none;
}
a:link
{
color: #0000FF;
text-decoration: none;
}
a:hover
{
color: #0000FF;
text-decoration: overline underline;
}
td
{
color: #000020;
font-family: verdana, lucidia, sans-serif;
font-size: 15px;
border: 1px solid #7F8FA9;
}
tr
{
background: #F2F6FC;
}
</style>
</head>
<body>
<table border="0" cellpadding="5" cellspacing="0">
<tr><td>
<p>Write successful!<br />AutoIndex configuration is finished.</p>
<p><a href="<?php echo $_SERVER['PHP_SELF']; ?>">Continue.</a></p>
</td></tr></table>
</body></html>
<?php
die();
}
}
//list of default settings
$settings = array(
'base_dir' => './',
'icon_path' => 'index_icons/winxp/',
'language' => 'en',
'template' => './templates/default/',
'log_file' => 'false',
'description_file' => 'false',
'user_list' => '.htpasswd.autoindex',
'download_count' => 'false',
'hidden_files' => 'hidden_files',
'banned_list' => 'false',
'show_dir_size' => 'true',
'use_login_system' => 'false',
'force_download' => 'false',
'search_enabled' => 'true',
'anti_leech' => 'false',
'must_login_to_download' => 'false',
'archive' => 'false',
'days_new' => '0',
'entries_per_page' => '0',
'thumbnail_height' => '0',
'bandwidth_limit' => '0',
'md5_show' => '0',
'parse_htaccess' => 'true'
);
global $config;
if (isset($config))
//if we're reconfiguring the script, use the current settings
{
foreach ($settings as $key => $data)
{
$settings[$key] = $config -> __get($key);
}
}
//begin display of main configuration page:
echo '<?xml version="1.0" encoding="iso-8859-1"?>';
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>AutoIndex Configuration Generator</title>
<style type="text/css" title="AutoIndex Default">
html, body
{
font-family: verdana, lucidia, sans-serif;
font-size: 14px;
background-color: #F0F0F0;
color: #000000;
}
a
{
color: #000000;
text-decoration: none;
}
hr
{
color: #000020;
background-color: #000020;
border: none;
width: 75%;
height: 1px;
}
h3
{
text-align: center;
color: #000000;
}
td
{
font-family: verdana, lucidia, sans-serif;
font-size: 14px;
color: #000000;
border: 1px solid #7F8FA9;
}
tr
{
background: #F2F6FC;
color: #000020;
}
.small
{
font-size: 11px;
color: #000000;
}
</style>
</head>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?action=config">
<h3>
<a href="http://autoindex.sourceforge.net/">AutoIndex PHP Script</a>
<br />Configuration
</h3>
<p>
The default options are currently selected, so just press the configure button at the bottom to use them.
</p>
<hr />
<p />
<table width="650" cellpadding="8"><tr><td>
Base Directory: <input type="text" name="base_dir" value="<?php if ($settings['base_dir'] != 'false') echo $settings['base_dir']; ?>" />
<p class="small">
This is the folder that will be the root of the directory listing.
<br />This will be the starting point for the script. Nothing above this directory can be viewed, but its subfolders can.
<br />Make sure to use a path relative to this index.php file if you can.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
Icon Path: <input type="text" name="icon_path" value="<?php if ($settings['icon_path'] != 'false') echo $settings['icon_path']; ?>" />
<p class="small">
This is the path to the icon image files (the path web browsers will access them from).
<br />The included icon sets are <em>apache</em>, <em>kde</em>, <em>osx</em>, and <em>winxp</em>.
<br />You can leave it blank to not show icons.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
<input type="checkbox" name="show_dir_size" value="true"<?php if ($settings['show_dir_size'] != 'false') echo ' checked="checked"'; ?> /> Show Directory Size
<p class="small">
If this box is checked, the total size of directories will be shown under size (all the folder's contents will be added up).
<br />Otherwise, it will display "[dir]" under size.
<br />NOTE: If you are trying to index many files (meaning a few thousand), you will notice a speed improvement with this turned off.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
<input type="checkbox" name="search_enabled" value="true"<?php if ($settings['search_enabled'] != 'false') echo ' checked="checked"'; ?> /> Enable Searching
<p class="small">
If this box is checked, people will be able to search for a file or folder by its filename.
<br />It will search the folder you are currently in, and all subfolders.
<br />Searching is not case sensitive.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
Template Directory: <input type="text" name="template" value="<?php if ($settings['template'] != 'false') echo $settings['template']; ?>" />
<p class="small">
This is the path where the *.tpl template files are located (relative to this index.php file).
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
<input type="checkbox" name="use_login_system" value="true"<?php if ($settings['use_login_system'] != 'false') echo ' checked="checked"'; ?> /> Enable Login System
<br /><input type="checkbox" name="must_login_to_download" value="true"<?php if ($settings['must_login_to_download'] != 'false') echo ' checked="checked"'; ?> /> Users must login to view/download
<br />User List: <input type="text" name="user_list" value="<?php if ($settings['user_list'] != 'false') echo $settings['user_list']; ?>" />
<p class="small">
User List contains the path to the text file where the usernames and encrypted passwords are stored.
<br />Make sure the file is chmod'ed so PHP can read and write to it.
<br />(User List is only needed if the login system is enabled.)
<br />
<br />The default accounts are:
<br /><code>username: admin</code>
<br /><code>password: admin</code>
<br />
<br /><code>username: user</code>
<br /><code>password: user</code>
<br />
<br />Be sure to create new accounts, then delete these default ones if you enable the login system!
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
Age for "New" Icon: <input type="text" name="days_new" size="3" value="<?php if ($settings['days_new'] != 'false') echo $settings['days_new']; ?>" /> days
<p class="small">
This contains the number of days old a file can be and still have [New] written next to it.
<br />If it is set to 0, this feature will be disabled.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
Number of file entires per page: <input type="text" name="entries_per_page" size="3" value="<?php if ($settings['entries_per_page'] != 'false') echo $settings['entries_per_page']; ?>" />
<p class="small">
This contains the number of files or folders to display on a single page.
If there are more files or folders, the display will be separated into different
pages with <code>Previous</code> and <code>Next</code> buttons.
<br />If it is set to 0, everything will be displayed on one page.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
Image Thumbnail Height: <input type="text" name="thumbnail_height" size="3" value="<?php if ($settings['thumbnail_height'] != 'false') echo $settings['thumbnail_height']; ?>" /> pixels
<p class="small">
This is a feature that will show thumbnails next to images. (NOTE: GDlib 2.0.1 or higher is required)
<br />Setting it to 0 will disable this feature, and setting it to any other number will set the size of the thumbnail.
<br />(100 is a good setting to start with.)
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
<input type="checkbox" name="force_download" value="true"<?php if ($settings['force_download'] != 'false') echo ' checked="checked"'; ?> /> Pipe downloaded files though the PHP script
<p>Bandwidth Limit: <input type="text" name="bandwidth_limit" size="3" value="<?php if ($settings['bandwidth_limit'] != 'false') echo $settings['bandwidth_limit']; ?>" /> KB/s</p>
<p class="small">
This contains the max download speed for files. The above checkbox needs to be checked for this to work.
<br />If it is set to 0, the script will not limit download speed.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
<p><input type="checkbox" name="anti_leech" value="true"<?php if ($settings['anti_leech'] != 'false') echo ' checked="checked"'; ?> /> Anti-Leech</p>
<p class="small">
When downloading a file, this will check to make sure the referrer the browser sends matches the website's URL.
<br />Since some people turn off referrer sending in their browser, this option is not recommended.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
<p>
The following items contain the path and filename to the file where the data for that feature will be stored.
<br />Leave it blank to turn off that feature.
</p>
<p>Hidden Files List: <input type="text" name="hidden_files" value="<?php if ($settings['hidden_files'] != 'false') echo $settings['hidden_files']; ?>" />
<br /><span class="small">
Any file or folder matched to an item in this list will be kept hidden.
<br />The contents of the list are editable when you login as an admin.
</span></p>
<p>Access Log File: <input type="text" name="log_file" value="<?php if ($settings['log_file'] != 'false') echo $settings['log_file']; ?>" />
<br /><span class="small">
The file to write the access log.
<br />If this is enabled, you will be able to view the contents of the logfile
<br />and generate statistics when you login as an admin.
</span></p>
<p>File/Folder Description File: <input type="text" name="description_file" value="<?php if ($settings['description_file'] != 'false') echo $settings['description_file']; ?>" />
<br /><span class="small">
The file to write the file descriptions to.
<br />File/Folder descriptions are editable when you login as an admin.
</span></p>
<p>Download Count File: <input type="text" name="download_count" value="<?php if ($settings['download_count'] != 'false') echo $settings['download_count']; ?>" />
<br /><span class="small">
The file to write the file download counts to.
<br />The count is automatically increased when a file is downloaded.
</span></p>
<p>Banned User List: <input type="text" name="banned_list" value="<?php if ($settings['banned_list'] != 'false') echo $settings['banned_list']; ?>" />
<br /><span class="small">
The file to write IP addresses and hostnames that are blocked from accessing this script.
<br />The contents of the list are editable when you login as an admin.
</span></p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
<input type="checkbox" name="archive" value="true"<?php if ($settings['archive'] != 'false') echo ' checked="checked"'; ?> /> Allow folder archive downloading
<p class="small">
If this box is checked, users will be able to download the folder's contents as a tar archive file.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
<input type="checkbox" name="parse_htaccess" value="true"<?php if ($settings['parse_htaccess'] != 'false') echo ' checked="checked"'; ?> /> Parse .htaccess files
<p class="small">
If this box is checked, .htaccess files will be parsed and used by AutoIndex.
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
<p>MD5 calculation max size: <input type="text" name="md5_show" size="3" value="<?php if ($settings['md5_show'] != 'false') echo $settings['md5_show']; ?>" /> MB</p>
<p class="small">
Setting this to 0 will disable this feature, and setting it to any other number will set the maximum size of a file to allow users to find the md5sum of (in megabytes).
<br />(10 is a good setting to start with.)
</p>
</td></tr></table>
<p />
<table width="650" cellpadding="8"><tr><td>
Default Language: <select name="language">
<?php
$l = Language::get_all_langs(PATH_TO_LANGUAGES);
if ($l === false)
{
$l = array('en');
}
sort($l);
foreach ($l as $lang)
{
$sel = (($lang == $settings['language']) ? ' selected="selected"' : '');
echo "\t\t<option$sel>$lang</option>\n";
}
?>
</select>
<p class="small">
The user's browser's default language is used, unless that language is
not available in AutoIndex. In that case, the language selected here is
used.
</p>
</td></tr></table>
<p /><hr /><p />
<p>
<input type="submit" value="Configure" />
</p>
<p>
When you press <em>Configure</em>, the script will attempt to write the config data to the file.
<br />If it cannot (for example if it does not have write permission in the directory) the config file will be downloaded, and you will have to upload it to your server.
<br />(It should be named <em><?php echo CONFIG_STORED; ?></em> and put in the same folder as <em>index.php</em>)
</p>
</form>
<!--
Powered by AutoIndex PHP Script (version <?php echo VERSION; ?>)
Copyright (C) 2002-2007 Justin Hagstrom
http://autoindex.sourceforge.net
Page generated in <?php echo round((microtime(true) - START_TIME) * 1000, 1); ?> milliseconds.
-->
</body></html>

7
hidden_files Executable file
View File

@@ -0,0 +1,7 @@
hidden_files
.ht*
*.php
classes
index_icons
languages
templates

643
index.php Executable file
View File

@@ -0,0 +1,643 @@
<?php
/**
* Handles all requests by the browser. This is the only file that can be
* accessed directly.
*
* @package AutoIndex
* @author Justin Hagstrom <JustinHagstrom@yahoo.com>
* @version 1.2.1 (January 06, 2007)
*
* @copyright Copyright (C) 2002-2007 Justin Hagstrom
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
*
* @link http://autoindex.sourceforge.net
*/
/*
AutoIndex PHP Script is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AutoIndex PHP Script 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* OPTIONAL SETTINGS:
*/
//filenames and paths for configuration related files
define('CONFIG_STORED', 'AutoIndex.conf.php');
define('CONFIG_GENERATOR', 'config.php');
//paths for files that will be included
define('PATH_TO_CLASSES', './classes/');
define('PATH_TO_LANGUAGES', './languages/');
define('LANGUAGE_FILE_EXT', '.txt');
//filenames of template files
define('GLOBAL_HEADER', 'global_header.tpl');
define('GLOBAL_FOOTER', 'global_footer.tpl');
define('TABLE_HEADER', 'table_header.tpl');
define('TABLE_FOOTER', 'table_footer.tpl');
define('EACH_FILE', 'each_file.tpl');
/**
* When ENABLE_CACHE is true, the indexes of directories will be stored in
* files in the folder CACHE_STORAGE_DIR. You will notice a speed improvement
* when viewing folders that contain a few thousand files. However, the contents
* of the indexed folders will not be updated until you delete the cache file.
*/
define('ENABLE_CACHE', false);
/**
* This is the folder cache data will be stored in. PHP needs write permission
* in this directory. You can use an absolute path or a relative path, just
* make sure there is a slash at the end.
*/
define('CACHE_STORAGE_DIR', './cache/');
/**
* Format to display dates in.
* @see date()
*/
define('DATE_FORMAT', 'Y-M-d');
/**
* Sets debug mode. Off (false) by default.
*/
define('DEBUG', false);
/* END OPTIONAL SETTINGS */
/** The time this script began to execute. */
define('START_TIME', microtime(true));
/** Level for disabled/banned accounts. */
define('BANNED', -1);
/** Level for Guest users (users who are not logged in). */
define('GUEST', 0);
/** Level for regular user accounts. */
define('USER', 1);
/** Level for moderator ("super user") accounts. */
define('MODERATOR', 2);
/** Level for Admin users. */
define('ADMIN', 3);
/**
* Minimum user level allowed to upload files.
* Use the ADMIN, MODERATOR, USER, GUEST constants.
* GUEST will allow non-logged-in users to upload.
*/
define('LEVEL_TO_UPLOAD', USER);
/** The version of AutoIndex PHP Script (the whole release, not based on individual files). */
define('VERSION', '2.2.4');
/**
* This must be set to true for other included files to run. Setting it to
* false could be used to temporarily disable the script.
*/
define('IN_AUTOINDEX', true);
if (@get_magic_quotes_gpc())
//remove any slashes added by the "magic quotes" setting
{
$_GET = array_map('stripslashes', $_GET);
$_POST = array_map('stripslashes', $_POST);
}
@set_magic_quotes_runtime(0);
$_GET = array_change_key_case($_GET, CASE_LOWER);
$_POST = array_change_key_case($_POST, CASE_LOWER);
if (@ini_get('zlib.output_compression') == '1')
//compensate for compressed output set in php.ini
{
header('Content-Encoding: gzip');
}
/*
* Uncomment the following code to turn on strict XHTML 1.1 compliance in
* users' browsers. If you do this, make sure any changes you make to the
* template do not break XHTML 1.1 compliance.
*/
/*if (isset($_SERVER['HTTP_ACCEPT']) && preg_match('#application/(xhtml\+xml|\*)#i', $_SERVER['HTTP_ACCEPT']))
{
header('Content-Type: application/xhtml+xml');
}*/
session_name('AutoIndex2');
session_start();
/**
* Formats $text within valid XHTML 1.1 tags and doctype.
*
* @param string $text
* @param string $title
* @return string
*/
function simple_display($text, $title = 'Error on Page')
{
return '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>' . $title . '</title>
<style type="text/css" title="AutoIndex Default">
html, body
{
font-family: verdana, lucidia, sans-serif;
font-size: 13px;
background-color: #F0F0F0;
color: #000000;
}
</style>
</head>
<body>
<p>' . $text . '</p></body></html>
<!--
Powered by AutoIndex PHP Script (version ' . VERSION . ')
Copyright (C) 2002-2007 Justin Hagstrom
http://autoindex.sourceforge.net
-->
';
}
/**
* This function is automatically called by PHP when an undefined class is
* called.
*
* A file with the classname followed by .php is included to load the class.
* The class should start with an upper-case letter with each new word also in
* upper-case. The filename must match the class name (including case).
*
* @param string $class The name of the undefined class
*/
function __autoload($class)
{
if ($class != 'self')
{
$file = PATH_TO_CLASSES . $class . '.php';
/** Try to load the class file. */
if (!@include_once($file))
{
die(simple_display('Error including file <em>'
. htmlentities($file) . '</em> - cannot load class.'));
}
}
}
/**
* This is used to report a fatal error that we cannot display with the Display
* class. All Exceptions used in AutoIndex should inherit from this class.
*
* @package AutoIndex
*/
class ExceptionFatal extends Exception {}
try
{
//now we need to include either the stored settings, or the config generator:
if (@is_file(CONFIG_STORED))
{
if (!@is_readable(CONFIG_STORED))
{
throw new ExceptionFatal('Make sure PHP has permission to read the file <em>'
. Url::html_output(CONFIG_STORED) . '</em>');
}
$config = new ConfigData(CONFIG_STORED);
}
else if (@is_file(CONFIG_GENERATOR))
{
/** Include the config generator so a new config file can be created. */
if (!@include_once(CONFIG_GENERATOR))
{
throw new ExceptionFatal('Error including file <em>'
. Url::html_output(CONFIG_GENERATOR) . '</em>');
}
die();
}
else
{
throw new ExceptionFatal('Neither <em>'
. Url::html_output(CONFIG_GENERATOR) . '</em> nor <em>'
. Url::html_output(CONFIG_STORED) . '</em> could be found.');
}
//find and store the user's IP address and hostname:
$ip = (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'N/A');
if (isset($_SESSION['host']))
{
$host = $_SESSION['host'];
}
else
{
$_SESSION['host'] = $host = @gethostbyaddr($ip);
}
//Create a language object:
$words = new Language();
//Create a logging object:
$log = new Logging($config -> __get('log_file'));
foreach ($config as $key => $item)
/* Go through each config setting, and set a constant with each setting's
* name to either true or false depending on if the config setting is
* enabled.
*/
{
$key = strtoupper($key);
if (defined($key))
{
throw new ExceptionFatal(Url::html_output($key)
. ' is already defined in <em>' . basename(Url::html_output($_SERVER['PHP_SELF']))
. '</em>, and should not be in the config file.');
}
define($key, ($item != 'false' && $item != '0'));
}
//make sure all required settings are set in the config file
foreach (array('base_dir', 'icon_path', 'language', 'template',
'log_file', 'description_file', 'user_list', 'download_count',
'hidden_files', 'banned_list', 'show_dir_size', 'use_login_system',
'force_download', 'search_enabled', 'anti_leech', 'entries_per_page',
'must_login_to_download', 'archive', 'days_new', 'thumbnail_height',
'bandwidth_limit', 'md5_show', 'parse_htaccess') as $set)
{
if (!defined(strtoupper($set)))
{
throw new ExceptionFatal('Required setting <em>' . $set
. '</em> is not set in <em>' . Url::html_output(CONFIG_STORED)
. '</em>');
}
}
/* From this point on, we can throw ExceptionDisplay rather than
* Exception since all the configuration is done.
*/
$b_list = $only_these_ips = $banned_ips = array();
if (BANNED_LIST && @is_file($config -> __get('banned_list')))
//make sure the user is not banned
{
$b_list = @file($config -> __get('banned_list'));
if ($b_list === false)
{
throw new ExceptionDisplay('Error reading from banned_list file.');
}
for ($i = 0; $i < count($b_list); $i++)
{
$b_list[$i] = rtrim($b_list[$i], "\r\n");
if (ConfigData::line_is_comment($b_list[$i]))
{
continue;
}
if ($b_list[$i]{0} === ':')
{
$only_these_ips[] = substr($b_list[$i], 1);
}
else
{
$banned_ips[] = $b_list[$i];
}
}
if (count($only_these_ips) > 0)
{
if (!(DirectoryList::match_in_array($ip, $only_these_ips) ||
DirectoryList::match_in_array($host, $only_these_ips)))
{
throw new ExceptionDisplay($words -> __get('the administrator has blocked your ip address or hostname') . '.');
}
}
else if (DirectoryList::match_in_array($ip, $banned_ips) ||
DirectoryList::match_in_array($host, $banned_ips))
{
throw new ExceptionDisplay($words -> __get('the administrator has blocked your ip address or hostname') . '.');
}
}
$show_only_these_files = $hidden_files = array();
if (HIDDEN_FILES && @is_file($config -> __get('hidden_files')))
//store the hidden file list in $hidden_list
{
$hidden_list = @file($config -> __get('hidden_files'));
if ($hidden_list === false)
{
throw new ExceptionDisplay('Error reading from "hidden_files" file.');
}
for ($i = 0; $i < count($hidden_list); $i++)
{
$hidden_list[$i] = rtrim($hidden_list[$i], "\r\n");
if (ConfigData::line_is_comment($hidden_list[$i]))
{
continue;
}
if ($hidden_list[$i]{0} === ':')
{
$show_only_these_files[] = substr($hidden_list[$i], 1);
}
else
{
$hidden_files[] = $hidden_list[$i];
}
}
}
//size of the "chunks" that are read at a time from the file (when $force_download is on)
$speed = (BANDWIDTH_LIMIT ? $config -> __get('bandwidth_limit') : 8);
if (DOWNLOAD_COUNT)
{
if (!@is_file($config -> __get('download_count')))
{
$h = @fopen($config -> __get('download_count'), 'wb');
if ($h === false)
{
throw new ExceptionDisplay('Could not open download count file for writing.'
. ' Make sure PHP has write permission to this file.');
}
fclose($h);
}
$downloads = new ConfigData($config -> __get('download_count'));
}
//create a user object:
$log_login = false;
if (USE_LOGIN_SYSTEM && isset($_POST['username'], $_POST['password'])
&& $_POST['username'] != '' && $_POST['password'] != '')
{
$you = new UserLoggedIn($_POST['username'], sha1($_POST['password']));
$log_login = true;
$_SESSION['password'] = sha1($_POST['password']);
unset($_POST['password']);
$_SESSION['username'] = $_POST['username'];
}
else if (USE_LOGIN_SYSTEM && isset($_SESSION['username'], $_SESSION['password']))
{
$you = new UserLoggedIn($_SESSION['username'], $_SESSION['password']);
}
else
{
$you = new User();
if (MUST_LOGIN_TO_DOWNLOAD && USE_LOGIN_SYSTEM)
{
$str = '<p>You must login to view and download files.</p>'
. '<table border="0" cellpadding="8" cellspacing="0">'
. '<tr class="paragraph"><td class="autoindex_td">'
. $you -> login_box() . '</td></tr></table>';
echo new Display($str);
die();
}
}
//set the logged in user's home directory:
$dir = Item::make_sure_slash((($you -> home_dir == '') ? $config -> __get('base_dir') : $you -> home_dir));
$config -> set('base_dir', $dir);
$subdir = '';
if (isset($_GET['dir']))
{
$dir .= Url::clean_input($_GET['dir']);
$dir = Item::make_sure_slash($dir);
if (!@is_dir($dir))
{
header('HTTP/1.0 404 Not Found');
$_GET['dir'] = ''; //so the "continue" link will work
throw new ExceptionDisplay('The directory <em>'
. Url::html_output($dir) . '</em> does not exist.');
}
$subdir = substr($dir, strlen($config -> __get('base_dir')));
if (isset($_GET['file']) && ($file = $_GET['file']))
{
while (preg_match('#\\\\|/$#', $file))
//remove all slashes from the end of the name
{
$file = substr($file, 0, -1);
}
$file = Url::clean_input($file);
if (!@is_file($dir . $file))
{
header('HTTP/1.0 404 Not Found');
throw new ExceptionDisplay('The file <em>'
. Url::html_output($file) . '</em> does not exist.');
}
if (ANTI_LEECH && !isset($_SESSION['ref']) && (!isset($_SERVER['HTTP_REFERER'])
|| stripos($_SERVER['HTTP_REFERER'], $_SERVER['SERVER_NAME']) === false))
{
$log -> add_entry('Leech Attempt');
$self = $_SERVER['SERVER_NAME'] . Url::html_output($_SERVER['PHP_SELF'])
. '?dir=' . Url::translate_uri($subdir);
throw new ExceptionDisplay('<h3>This PHP Script has an Anti-Leech feature turned on.</h3>'
. ' <p>Make sure you are accessing this file directly from <a class="autoindex_a" href="http://'
. $self . '">http://' . $self . '</a></p>');
}
$log -> add_entry($file);
if (DOWNLOAD_COUNT)
{
$downloads -> add_one($dir . $file);
}
$url = new Url($dir . $file, true);
$url -> download();
}
}
if ($log_login)
{
$log -> add_entry('Successful login (Username: '
. $_SESSION['username'] . ')');
}
if (DESCRIPTION_FILE)
{
$descriptions = new ConfigData((@is_file($config -> __get('description_file')))
? $config -> __get('description_file') : false);
}
if (PARSE_HTACCESS)
{
//parse .htaccess file(s)
new Htaccess($dir, '.htaccess');
}
if (MD5_SHOW && isset($_GET['md5']) && $_GET['md5'] != '')
{
$file = $dir . Url::clean_input($_GET['md5']);
if (!@is_file($file))
{
header('HTTP/1.0 404 Not Found');
throw new ExceptionDisplay('Cannot calculate md5sum: the file <em>'
. Url::html_output($file) . '</em> does not exist.');
}
$size = (int)@filesize($file);
if ($size <= 0 || $size / 1048576 > $config -> __get('md5_show'))
{
throw new ExceptionDisplay('Empty file, or file too big to calculate the'
. 'md5sum of (according to the $md5_show variable).');
}
die(simple_display(md5_file($file), 'md5sum of '
. Url::html_output($file)));
}
if (THUMBNAIL_HEIGHT && isset($_GET['thumbnail']))
{
$fn = Url::clean_input($_GET['thumbnail']);
if ($fn == '')
{
die();
}
echo new Image($fn);
}
if (ARCHIVE && isset($_GET['archive']))
{
$log -> add_entry('Directory archived');
$outfile = Item::get_basename($subdir);
if ($outfile == '' || $outfile == '.')
{
$outfile = 'base_dir';
}
$mime = new MimeType('.tar');
header('Content-Type: ' . $mime -> __toString());
header('Content-Disposition: attachment; filename="'
. $outfile . '.tar"');
@set_time_limit(0);
$list = new DirectoryList($dir);
$tar = new Tar($list, $outfile, strlen($dir));
die();
}
//set the sorting mode:
if (isset($_GET['sort']) && $_GET['sort'] != '')
{
$_SESSION['sort'] = $_GET['sort'];
}
else if (!isset($_SESSION['sort']))
{
$_SESSION['sort'] = 'filename'; //default sort mode
}
//set the sorting order:
if (isset($_GET['sort_mode']) && ($_GET['sort_mode'] == 'a' || $_GET['sort_mode'] == 'd'))
{
$_SESSION['sort_mode'] = $_GET['sort_mode'];
}
else if (!isset($_SESSION['sort_mode']))
{
$_SESSION['sort_mode'] = 'a'; //default sort order
}
if (count($_FILES) > 0)
//deal with any request to upload files:
{
$upload = new Upload($you); //the constructor checks if you have permission to upload
$upload -> do_upload();
}
if (USE_LOGIN_SYSTEM)
{
if (isset($_GET['logout']) && $_GET['logout'] == 'true')
{
$you -> logout();
}
else if (isset($_GET['action']) && $_GET['action'] != '')
{
$admin = new Admin($you); //the constructor checks if you really are an admin
$admin -> action($_GET['action']);
}
}
if (ANTI_LEECH && !isset($_SESSION['ref']))
{
$_SESSION['ref'] = true;
}
$search_log = '';
if (SEARCH_ENABLED && isset($_GET['search'], $_GET['search_mode'])
&& $_GET['search'] != '' && $_GET['search_mode'] != '')
{
$s = Url::clean_input($_GET['search']);
$dir_list = new Search($s, $dir, $_GET['search_mode']);
$search_log = "Search: $s";
}
else if (ENABLE_CACHE)
{
$cache = CACHE_STORAGE_DIR . strtr($dir, '\/:', '---'); //path to cache file
if (@is_file($cache))
{
$contents = @file_get_contents($cache);
if ($contents === false)
{
throw new ExceptionDisplay('Cannot open cache file for reading. Make sure PHP has read permission for these files.');
}
$dir_list = unserialize($contents);
}
else
{
$dir_list = new DirectoryListDetailed($dir);
if (!@is_dir(CACHE_STORAGE_DIR))
{
if (!Admin::mkdir_recursive(CACHE_STORAGE_DIR))
//Attempt to create the directory. If it fails, tell the user to manually make the folder.
{
throw new ExceptionDisplay('Please create the directory <em>'
. Url::html_output(CACHE_STORAGE_DIR)
. '</em> so cache files can be written.');
}
}
$h = @fopen($cache, 'wb');
if ($h === false)
{
throw new ExceptionDisplay('Cannot write to cache file. Make sure PHP has write permission in the cache directory.');
}
fwrite($h, serialize($dir_list));
fclose($h);
}
}
else
{
$page = ((ENTRIES_PER_PAGE && isset($_GET['page'])) ? (int)$_GET['page'] : 1);
$dir_list = new DirectoryListDetailed($dir, $page);
$max_page = (ENTRIES_PER_PAGE ? (ceil($dir_list -> total_items() / $config -> __get('entries_per_page'))) : 1);
}
$log -> add_entry($search_log);
$str = $dir_list -> __toString();
echo new Display($str);
}
catch (ExceptionDisplay $e)
{
echo $e;
}
catch (Exception $e)
{
echo simple_display($e -> getMessage());
}
?>

BIN
index_icons/apache/back.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

BIN
index_icons/apache/binary.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

BIN
index_icons/apache/binhex.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

BIN
index_icons/apache/cd.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

BIN
index_icons/apache/comp.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

BIN
index_icons/apache/compressed.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

BIN
index_icons/apache/dir.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

BIN
index_icons/apache/dll.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

BIN
index_icons/apache/doc.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

BIN
index_icons/apache/generic.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

BIN
index_icons/apache/image.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

BIN
index_icons/apache/java.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
index_icons/apache/js.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

BIN
index_icons/apache/key.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

BIN
index_icons/apache/login.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

BIN
index_icons/apache/mov.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

BIN
index_icons/apache/movie.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

BIN
index_icons/apache/new.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

BIN
index_icons/apache/pdf.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

BIN
index_icons/apache/php.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

BIN
index_icons/apache/ppt.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

BIN
index_icons/apache/ps.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

BIN
index_icons/apache/search.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

BIN
index_icons/apache/sound.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

BIN
index_icons/apache/tar.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

BIN
index_icons/apache/text.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

BIN
index_icons/apache/unknown.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

BIN
index_icons/apache/uu.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

BIN
index_icons/apache/web.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

BIN
index_icons/apache/xls.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

BIN
index_icons/kde/back.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

BIN
index_icons/kde/binary.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

BIN
index_icons/kde/binhex.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

BIN
index_icons/kde/cd.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

BIN
index_icons/kde/comp.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

BIN
index_icons/kde/compressed.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

BIN
index_icons/kde/dir.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

BIN
index_icons/kde/dll.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

BIN
index_icons/kde/doc.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

BIN
index_icons/kde/generic.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

BIN
index_icons/kde/image.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

BIN
index_icons/kde/java.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

BIN
index_icons/kde/js.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

BIN
index_icons/kde/key.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

BIN
index_icons/kde/login.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

BIN
index_icons/kde/mov.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

BIN
index_icons/kde/movie.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

BIN
index_icons/kde/new.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

BIN
index_icons/kde/pdf.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

BIN
index_icons/kde/php.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

BIN
index_icons/kde/ppt.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

BIN
index_icons/kde/ps.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

BIN
index_icons/kde/search.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

BIN
index_icons/kde/sound.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

BIN
index_icons/kde/tar.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

BIN
index_icons/kde/text.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

BIN
index_icons/kde/unknown.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

BIN
index_icons/kde/uu.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

BIN
index_icons/kde/web.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

BIN
index_icons/kde/xls.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

BIN
index_icons/osx/back.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

BIN
index_icons/osx/binary.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

BIN
index_icons/osx/binhex.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

BIN
index_icons/osx/cd.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

BIN
index_icons/osx/comp.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

BIN
index_icons/osx/compressed.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

BIN
index_icons/osx/dir.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Some files were not shown because too many files have changed in this diff Show More