From af3250238da8a5f3ef6bc1783a473ba2f1580b54 Mon Sep 17 00:00:00 2001 From: Florin-Ciprian Bodin Date: Tue, 26 Dec 2023 08:50:59 +0200 Subject: [PATCH] Update index.php Small final edits. --- index.php | 1356 ++++++++++++++++++++++++++--------------------------- 1 file changed, 674 insertions(+), 682 deletions(-) diff --git a/index.php b/index.php index b30dcd8..75818f0 100644 --- a/index.php +++ b/index.php @@ -1,682 +1,674 @@ -, FlorinCB - * @version 2 (January 01, 2019 / 09, November, 2023) - * @version $Id: index.php, v 2.2.7 2023/11/15 08:08:08 orynider Exp $ - * @copyright Copyright (C) 2002-2008 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 -*/ - -ini_set('display_errors', '1'); -//@error_reporting(E_ALL & ~E_NOTICE); -session_cache_expire (1440); -@set_time_limit (1500); -define('ENVIRONMENT', 'production'); - -/** - * OPTIONAL SETTINGS: 'production' or 'development' - */ -if (!defined('ENVIRONMENT')) -{ - @define('ENVIRONMENT', 'development'); -} - -$phpEx = substr(strrchr(__FILE__, '.'), true); - -//filenames and paths for configuration related files -/*EDIT*/$CONFIG_PATH = './'; -/*EDIT*/define('ROOT_PATH', $CONFIG_PATH); -/*EDIT*/define('CONFIG_STORED', $CONFIG_PATH . 'AutoIndex.conf.'.$phpEx); -/*EDIT*/define('CONFIG_GENERATOR', $CONFIG_PATH . 'config.'.$phpEx); - - -//paths for files that will be included -/*EDIT*/define('PATH_TO_CLASSES', $CONFIG_PATH . 'classes/'); -/*EDIT*/define('PATH_TO_LANGUAGES', $CONFIG_PATH . 'languages/'); - -//paths for configurable directories we need at install -/*EDIT* *FLAGS_PATH*/define('PATH_TO_FLAGS', $CONFIG_PATH . 'flags/'); -/*EDIT* *ICONS_PATH*/define('PATH_TO_ICONS', $CONFIG_PATH . 'index_icons/'); -/*EDIT* *ASSETS_PATH*/define('PATH_TO_ASSETS', $CONFIG_PATH . 'assets/'); -/*EDIT* *TEMPLATE_PATH*/define('PATH_TO_TEMPLATES', $CONFIG_PATH . 'templates/'); - -define('LANGUAGE_FILE_EXT', '.txt'); -define('TPL_EXT', 'tpl'); - -//filenames of template files -define('GLOBAL_HEADER', 'global_header.'.TPL_EXT); -define('GLOBAL_FOOTER', 'global_footer.'.TPL_EXT); -define('TABLE_HEADER', 'table_header.'.TPL_EXT); -define('TABLE_FOOTER', 'table_footer.'.TPL_EXT); -define('EACH_FILE', 'each_file.'.TPL_EXT); - -/** - * 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. - */ -/*EDIT*/define('CACHE_STORAGE_DIR', '../AutoIndex/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. - */ -/*EDIT*/define('LEVEL_TO_UPLOAD', ADMIN); -//define('LEVEL_TO_UPLOAD', USER); - -/** The version of AutoIndex PHP Script (the whole release, not based on individual files). */ -define('VERSION', '2.2.7'); - -/** - * 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); - -//compensate for compressed output set in php.ini -if (ini_get('zlib.output_compression') == '1') -{ - 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 (!empty($_SERVER['HTTP_ACCEPT']) && preg_match('#application/(xhtml\+xml|\*)#i', $_SERVER['HTTP_ACCEPT'])) -{ - header('Content-Type: application/xhtml+xml'); -}*/ - -session_name('AutoIndex2'); -session_start(); - -//echo 'PHP_VERSION: '.PHP_VERSION; -/** - * 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', $notify = '', $return_index = "index.php") -{ - return ' - - - -' . $title . ' - - - -

' . $text . '

- - - - - -'; -} - -/** - * 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 ' . htmlentities($file) . ' - cannot load class.')); - } - } -} - -/* -* Instantiate the mx_request_vars class -* make sure to do before it's ever used -*/ -$request = new RequestVars('', false); - -// this is needed to prevent unicode normalization -$super_globals_disabled = $request->super_globals_disabled(); - -// enable super globals to get literal value -if (!$super_globals_disabled) -{ - //$request->disable_super_globals(); -} - - - -/* To do: Should be switched to i.e. $request->request('style', 1); -*/ -$_GET = array_change_key_case($_GET, CASE_LOWER); -$_POST = array_change_key_case($_POST, CASE_LOWER); - - -/** - * 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 -{ - if (is_file(CONFIG_STORED)) //now we need to include either the stored settings, or the config generator: - { - if (!is_readable(CONFIG_STORED)) - { - throw new ExceptionFatal('Make sure PHP has permission to read the file ' . Url::html_output(CONFIG_STORED) . ''); - } - $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 ' . Url::html_output(CONFIG_GENERATOR) . ''); - } - exit(); - die('exit.. ?'); - } - else - { - throw new ExceptionFatal('Neither ' . Url::html_output(CONFIG_GENERATOR) . ' nor ' . Url::html_output(CONFIG_STORED) . ' could be found.'); - } - - //find and store the user's IP address and hostname: $ip = (!empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'N/A'); - $ip = $request->server('HTTP_X_FORWARDED_FOR') ? htmlspecialchars_decode($request->server('HTTP_X_FORWARDED_FOR')) : $request->server('REMOTE_ADDR'); - if (!empty($_SESSION['host'])) - { - $host = $_SESSION['host']; - } - else - { - $_SESSION['host'] = $host = gethostbyaddr($ip); - } - - //Create a language object: - $words = new Language(); - - /* - * Instantiate the Mobile Device Detect class - * make sure to do before it's ever used - */ - $mobile_device_detect = new MobileDeviceDetect(); - $status = $mobile_device_detect->mobile_device_detect(); - - //Create a logging object: - $log = new Logging($config->__get('log_file')); - - /** - * 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. - */ - foreach ($config as $key => $item) - { - $key = strtoupper($key); - if (defined($key)) - { - throw new ExceptionFatal(Url::html_output($key) . ' is already defined in ' . basename(Url::html_output($_SERVER['PHP_SELF'])) . ', 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', 'flag_path', 'language', 'assets_path', '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 ' . $set . ' is not set in ' . Url::html_output(CONFIG_STORED) . ''); - } - } - - - /** - * 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; - $username = $request->is_set_post('username') ? $request->post('username') : ''; - $password = $request->is_set_post('password') ? $request->post('password') : ''; - if (USE_LOGIN_SYSTEM && !empty($username) && ($username != '') && ($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 && !empty($_SESSION['username'])) - { - $you = new UserLoggedIn($_SESSION['username'], $_SESSION['password']); - } - else - { - $you = new User(); - if (MUST_LOGIN_TO_DOWNLOAD && USE_LOGIN_SYSTEM) - { - $str = '

You must login to view and download files.

- - - - -
- ' . $you->login_box() . ' -
'; - 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 ($request->is_not_empty_get('dir')) - { - $dir .= Url::clean_input($request->get('dir')); - $dir = Item::make_sure_slash($dir); - - if (!is_dir($dir)) - { - header('HTTP/1.0 404 Not Found'); - $request->recursive_set_var('dir', '', TYPE_GET_VARS); //so the "continue" link will work - throw new ExceptionDisplay('The directory ' . Url::html_output($dir) . ' does not exist.'); - } - - $subdir = substr($dir, strlen($config->__get('base_dir'))); - if ($request->is_set_get('file') && ($file = $request->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 ' . Url::html_output($file) . ' does not exist.'); - } - if (ANTI_LEECH && !!empty($_SESSION['ref']) && (!!$request->server('HTTP_REFERER') || stripos($request->server('HTTP_REFERER'), $request->server('SERVER_NAME')) === false)) - { - $log->add_entry('Leech Attempt'); - $self = $request->server('SERVER_NAME') . Url::html_output($request->server('PHP_SELF')) . '?dir=' . Url::translate_uri($subdir); - throw new ExceptionDisplay('

This PHP Script has an Anti-Leech feature turned on.

' . '

Make sure you are accessing this file directly from http://' . $self . '

'); - } - $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 && $request->is_set_get('md5')) - { - $file = $dir . Url::clean_input($request->get('md5')); - if (!is_file($file)) - { - header('HTTP/1.0 404 Not Found'); - throw new ExceptionDisplay('Cannot calculate md5sum: the file ' . Url::html_output($file) . ' 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 && $request->is_set_get('thumbnail')) - { - $fn = Url::clean_input($request->get('thumbnail')); - if ($fn == '') - { - die(); - } - echo new Image($fn); - } - - if (ARCHIVE && $request->is_set_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(); - } - - if (THUMBNAIL_HEIGHT && $request->is_set_get('thm')) - { - $fn = Url::clean_input($request->get('thm')); - if ($fn == '') - { - die(); - } - echo new Stream($fn); - } - - //set the sorting mode: - if ($request->is_set_get('sort')) - { - $_SESSION['sort'] = $request->get('sort'); - } - else if (!!empty($_SESSION['sort'])) - { - $_SESSION['sort'] = 'filename'; //default sort mode - } - - //set the sorting order: - if ($request->is_set_get('sort_mode')) - { - if ($request->get('sort_mode') == 'a' || $request->get('sort_mode') == 'd') - { - $_SESSION['sort_mode'] = $request->get('sort_mode'); - } - } - else if (!!empty($_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) - { - $logout = $request->is_set_get('logout') ? $request->get('logout') : 'false'; - $action = $request->is_set_get('action') ? $request->get('action') : ''; - - if ($request->is_not_empty_get('logout') && $logout == 'true') - { - $you->logout(); - } - else if ($request->is_not_empty_get('action') && $action != '') - { - $admin = new Admin($you); //the constructor checks if you really are an admin - $admin->action($action); - } - } - - if (ANTI_LEECH && !!empty($_SESSION['ref'])) - { - $_SESSION['ref'] = true; - } - - $search_log = ''; - if (SEARCH_ENABLED && $request->is_set_get('search')) - { - $s = Url::clean_input($request->get('search')); - $dir_list = new Search($s, $dir, $request->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 ' . Url::html_output(CACHE_STORAGE_DIR) . ' 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 && $request->is_set_get('page')) ? (int) $request->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); - echo $mobile_device_detect->detect()->getInfo(); -} -catch (ExceptionDisplay $e) -{ - echo $e; -} -catch (Exception $e) -{ - echo simple_display($e->getMessage()); -} -?> \ No newline at end of file +, FlorinCB + * @version 2 (January 01, 2019 / 09, November, 2023) + * @version $Id: index.php, v 2.2.7 2023/11/15 08:08:08 orynider Exp $ + * @copyright Copyright (C) 2002-2008 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 +*/ + +ini_set('display_errors', '1'); +//@error_reporting(E_ALL & ~E_NOTICE); +session_cache_expire (1440); +@set_time_limit (1500); +define('ENVIRONMENT', 'production'); + +/** + * OPTIONAL SETTINGS: 'production' or 'development' + */ +if (!defined('ENVIRONMENT')) +{ + @define('ENVIRONMENT', 'development'); +} + +$phpEx = substr(strrchr(__FILE__, '.'), true); + +//filenames and paths for configuration related files +/*EDIT*/$CONFIG_PATH = './'; +/*EDIT*/define('ROOT_PATH', $CONFIG_PATH); +/*EDIT*/define('CONFIG_STORED', $CONFIG_PATH . 'AutoIndex.conf.'.$phpEx); +/*EDIT*/define('CONFIG_GENERATOR', $CONFIG_PATH . 'config.'.$phpEx); + + +//paths for files that will be included +/*EDIT*/define('PATH_TO_CLASSES', $CONFIG_PATH . 'classes/'); +/*EDIT*/define('PATH_TO_LANGUAGES', $CONFIG_PATH . 'languages/'); + +//paths for configurable directories we need at install +/*EDIT* *FLAGS_PATH*/define('PATH_TO_FLAGS', $CONFIG_PATH . 'flags/'); +/*EDIT* *ICONS_PATH*/define('PATH_TO_ICONS', $CONFIG_PATH . 'index_icons/'); +/*EDIT* *ASSETS_PATH*/define('PATH_TO_ASSETS', $CONFIG_PATH . 'assets/'); +/*EDIT* *TEMPLATE_PATH*/define('PATH_TO_TEMPLATES', $CONFIG_PATH . 'templates/'); + +define('LANGUAGE_FILE_EXT', '.txt'); +define('TPL_EXT', 'tpl'); + +//filenames of template files +define('GLOBAL_HEADER', 'global_header.'.TPL_EXT); +define('GLOBAL_FOOTER', 'global_footer.'.TPL_EXT); +define('TABLE_HEADER', 'table_header.'.TPL_EXT); +define('TABLE_FOOTER', 'table_footer.'.TPL_EXT); +define('EACH_FILE', 'each_file.'.TPL_EXT); + +/** + * 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. + */ +/*EDIT*/define('CACHE_STORAGE_DIR', '../AutoIndex/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. + */ +/*EDIT*/define('LEVEL_TO_UPLOAD', ADMIN); +//define('LEVEL_TO_UPLOAD', USER); + +/** The version of AutoIndex PHP Script (the whole release, not based on individual files). */ +define('VERSION', '2.2.7'); + +/** + * 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); + +//compensate for compressed output set in php.ini +if (ini_get('zlib.output_compression') == '1') +{ + 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 (!empty($_SERVER['HTTP_ACCEPT']) && preg_match('#application/(xhtml\+xml|\*)#i', $_SERVER['HTTP_ACCEPT'])) +{ + header('Content-Type: application/xhtml+xml'); +}*/ + +session_name('AutoIndex2'); +session_start(); + +//echo 'PHP_VERSION: '.PHP_VERSION; +/** + * 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', $notify = '', $return_index = "index.php") +{ + return ' + ' . $title . ' + +

' . $text . '

+ + + + '; +} + +/** + * 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 ' . htmlentities($file) . ' - cannot load class.')); + } + } +} + +/* +* Instantiate the mx_request_vars class +* make sure to do before it's ever used +*/ +$request = new RequestVars('', false); + +// this is needed to prevent unicode normalization +$super_globals_disabled = $request->super_globals_disabled(); + +// enable super globals to get literal value +if (!$super_globals_disabled) +{ + //$request->disable_super_globals(); +} + + + +/* To do: Should be switched to i.e. $request->request('style', 1); +*/ +$_GET = array_change_key_case($_GET, CASE_LOWER); +$_POST = array_change_key_case($_POST, CASE_LOWER); + + +/** + * 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 +{ + if (is_file(CONFIG_STORED)) //now we need to include either the stored settings, or the config generator: + { + if (!is_readable(CONFIG_STORED)) + { + throw new ExceptionFatal('Make sure PHP has permission to read the file ' . Url::html_output(CONFIG_STORED) . ''); + } + $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 ' . Url::html_output(CONFIG_GENERATOR) . ''); + } + exit(); + die('exit.. ?'); + } + else + { + throw new ExceptionFatal('Neither ' . Url::html_output(CONFIG_GENERATOR) . ' nor ' . Url::html_output(CONFIG_STORED) . ' could be found.'); + } + + //find and store the user's IP address and hostname: $ip = (!empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'N/A'); + $ip = $request->server('HTTP_X_FORWARDED_FOR') ? htmlspecialchars_decode($request->server('HTTP_X_FORWARDED_FOR')) : $request->server('REMOTE_ADDR'); + if (!empty($_SESSION['host'])) + { + $host = $_SESSION['host']; + } + else + { + $_SESSION['host'] = $host = gethostbyaddr($ip); + } + + //Create a language object: + $words = new Language(); + + /* + * Instantiate the Mobile Device Detect class + * make sure to do before it's ever used + */ + $mobile_device_detect = new MobileDeviceDetect(); + $status = $mobile_device_detect->mobile_device_detect(); + + //Create a logging object: + $log = new Logging($config->__get('log_file')); + + /** + * 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. + */ + foreach ($config as $key => $item) + { + $key = strtoupper($key); + if (defined($key)) + { + throw new ExceptionFatal(Url::html_output($key) . ' is already defined in ' . basename(Url::html_output($_SERVER['PHP_SELF'])) . ', 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', 'flag_path', 'language', 'assets_path', '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 ' . $set . ' is not set in ' . Url::html_output(CONFIG_STORED) . ''); + } + } + + + /** + * 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; + $username = $request->is_set_post('username') ? $request->post('username') : ''; + $password = $request->is_set_post('password') ? $request->post('password') : ''; + if (USE_LOGIN_SYSTEM && !empty($username) && ($username != '') && ($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 && !empty($_SESSION['username'])) + { + $you = new UserLoggedIn($_SESSION['username'], $_SESSION['password']); + } + else + { + $you = new User(); + if (MUST_LOGIN_TO_DOWNLOAD && USE_LOGIN_SYSTEM) + { + $str = '

You must login to view and download files.

+ + + + +
+ ' . $you->login_box() . ' +
'; + 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 ($request->is_not_empty_get('dir')) + { + $dir .= Url::clean_input($request->get('dir')); + $dir = Item::make_sure_slash($dir); + + if (!is_dir($dir)) + { + header('HTTP/1.0 404 Not Found'); + $request->recursive_set_var('dir', '', TYPE_GET_VARS); //so the "continue" link will work + throw new ExceptionDisplay('The directory ' . Url::html_output($dir) . ' does not exist.'); + } + + $subdir = substr($dir, strlen($config->__get('base_dir'))); + if ($request->is_set_get('file') && ($file = $request->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 ' . Url::html_output($file) . ' does not exist.'); + } + if (ANTI_LEECH && !!empty($_SESSION['ref']) && (!!$request->server('HTTP_REFERER') || stripos($request->server('HTTP_REFERER'), $request->server('SERVER_NAME')) === false)) + { + $log->add_entry('Leech Attempt'); + $self = $request->server('SERVER_NAME') . Url::html_output($request->server('PHP_SELF')) . '?dir=' . Url::translate_uri($subdir); + throw new ExceptionDisplay('

This PHP Script has an Anti-Leech feature turned on.

' . '

Make sure you are accessing this file directly from http://' . $self . '

'); + } + $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 && $request->is_set_get('md5')) + { + $file = $dir . Url::clean_input($request->get('md5')); + if (!is_file($file)) + { + header('HTTP/1.0 404 Not Found'); + throw new ExceptionDisplay('Cannot calculate md5sum: the file ' . Url::html_output($file) . ' 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 && $request->is_set_get('thumbnail')) + { + $fn = Url::clean_input($request->get('thumbnail')); + if ($fn == '') + { + die(); + } + echo new Image($fn); + } + + if (ARCHIVE && $request->is_set_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(); + } + + if (THUMBNAIL_HEIGHT && $request->is_set_get('thm')) + { + $fn = Url::clean_input($request->get('thm')); + if ($fn == '') + { + die(); + } + echo new Stream($fn); + } + + //set the sorting mode: + if ($request->is_set_get('sort')) + { + $_SESSION['sort'] = $request->get('sort'); + } + else if (!!empty($_SESSION['sort'])) + { + $_SESSION['sort'] = 'filename'; //default sort mode + } + + //set the sorting order: + if ($request->is_set_get('sort_mode')) + { + if ($request->get('sort_mode') == 'a' || $request->get('sort_mode') == 'd') + { + $_SESSION['sort_mode'] = $request->get('sort_mode'); + } + } + else if (!!empty($_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) + { + $logout = $request->is_set_get('logout') ? $request->get('logout') : 'false'; + $action = $request->is_set_get('action') ? $request->get('action') : ''; + + if ($request->is_not_empty_get('logout') && $logout == 'true') + { + $you->logout(); + } + else if ($request->is_not_empty_get('action') && $action != '') + { + $admin = new Admin($you); //the constructor checks if you really are an admin + $admin->action($action); + } + } + + if (ANTI_LEECH && !!empty($_SESSION['ref'])) + { + $_SESSION['ref'] = true; + } + + $search_log = ''; + if (SEARCH_ENABLED && $request->is_set_get('search')) + { + $s = Url::clean_input($request->get('search')); + $dir_list = new Search($s, $dir, $request->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 ' . Url::html_output(CACHE_STORAGE_DIR) . ' 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 && $request->is_set_get('page')) ? (int) $request->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); + //echo $mobile_device_detect->detect()->getInfo(); +} +catch (ExceptionDisplay $e) +{ + echo $e; +} +catch (Exception $e) +{ + echo simple_display($e->getMessage()); +} +?>