ich habe dazu eine Extension (Directory Listing 1.1 von Serge Gebhardt <sg@mystaz.de>) umgeschrieben, so dass sie den Link leicht verschlüsselt an ein eigenes phpscript übergibt, welches ja lokalen (Lese-)Zugriff trotz .htaccess-beschränkung für den Webserver hat. Der Vorteil hierbei ist für mich auch noch, dass z.B. JPG-Bilder mit Übergröße nicht im Browser angezeigt werden, sondern ein "Save as..." Fenster aufgeht und man es auf Festplatte speichern kann (ohne Shift+linkemaus).
File: pi1/class.tx_dirlisting_pi1.php (18.1 K)
Code:
<?php
/***************************************************************
* Copyright notice
*
* (c) 2003 Serge Gebhardt (sg@mystaz.de - http://www.mystaz.de)
* All rights reserved
*
* This script is part of the Typo3 project. The Typo3 project 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.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This 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.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Plugin 'Directory listing' for the 'dir_listing' extension.
*
* @author Serge Gebhardt <sg@mystaz.de>
*
* Please note, that this extension is vaguely based on a script by
* Andreas Baumgart, http://andreas.slashdot.ch
* Icons were meanly stolen from his script, but with permission :smile:
*
* 2003, by Serge Gebhardt (sg(at)mystaz(dot)de - http://www.mystaz.de)
*/
require_once(PATH_tslib."class.tslib_pibase.php");
class tx_dirlisting_pi1 extends tslib_pibase {
var $prefixId = "tx_dirlisting_pi1"; // Same as class name
var $scriptRelPath = "pi1/class.tx_dirlisting_pi1.php"; // Path to this script relative to the extension dir.
var $extKey = "dir_listing"; // The extension key.
var $lvar = array(); // array for local variables. has the advantage
// of easy debugging through t3lib_div::debug()
/**
* main function, returns content
*/
function main($content,$conf) {
$this->conf=$conf;
$this->pi_setPiVarDefaults();
$this->pi_loadLL();
//$GLOBALS["TSFE"]->set_no_cache(); //###test with and without
$lvar = &$this->lvar; // i'm sick of writing "$this->" :smile:
$lvar["content"] = ""; // output from the plugin
$lvar["error"] = 0; // disable list if an error occurred
$lvar["readme_found"] = 0; // display a readme file before list?
$lvar["path_to_rep"] = $this->cObj->data["tx_dirlisting_path_to_rep"];
$lvar["path_in_rep"] = "";
// check configuration
if (substr($lvar["path_to_rep"],-1) != "/")
$lvar["path_to_rep"] .= "/";
if (!@is_readable($lvar["path_to_rep"]))
$this->error("could_not_open", ' "'.$lvar["path_to_rep"].'"');
if (!strlen($conf["url_var_path"]))
$this->error("url_var_empty", ' "url_var_path"');
if ($conf["asb_id"] >= 0 && !strlen($conf["asb_url_var_path"]))
$this->error("url_var_empty", ' "asb_url_var_path"');
// check the url_var_path
if (strlen($_GET[$conf["url_var_path"]])) {
if (substr($_GET[$conf["url_var_path"]],-1) != "/")
$lvar["path_in_rep"] = $_GET[$conf["url_var_path"]]."/";
else
$lvar["path_in_rep"] = $_GET[$conf["url_var_path"]];
if ($lvar["path_in_rep"]{0} == "/")
$lvar["path_in_rep"] = substr($lvar["path_in_rep"], 1);
$lvar["path_in_rep"] = str_replace("../", "",
$lvar["path_in_rep"]);
$lvar["path_in_rep"] = str_replace("./", "",
$lvar["path_in_rep"]);
}
else
$lvar["path_in_rep"] = "";
// i am lazy, so i need this :smile:
$lvar["path"] = $lvar["path_to_rep"].$lvar["path_in_rep"];
// split up the path for easy links in the titlebar
$tmp_dirlist = explode("/", $lvar["path_in_rep"]);
$tmp_dirstr = "";
$lvar["title_path_link"][0] = dirname($lvar["path_to_rep"]);
$lvar["title_path_link"][1] = array(
basename($lvar["path_to_rep"]),
""
);
for ($i=0; $i<count($tmp_dirlist)-1; $i++) {
$tmp_dirstr .= $tmp_dirlist[$i]."/";
$lvar["title_path_link"][] = array(
$tmp_dirlist[$i],
$tmp_dirstr
);
}
// open folder and make a list of content
if ($handle= @opendir($lvar["path"])) {
while (false !== ($fn = readdir($handle))) {
// some files we don't want to appear
if (!strcmp($fn, ".htaccess") || !strcmp($fn, ".htpasswd"))
continue;
if ($fn == ".")
continue;
if (!strcmp($fn, "..") && !strlen($lvar["path_in_rep"]))
continue;
if (!$conf["list_hidden"] && $fn{0} == "." && strcmp($fn, ".."))
continue;
// display a readme file?
if (strcmp($conf["readme_file"], $fn) == 0 &&
!@is_dir($lvar["path"].$fn)) {
$lvar["readme_found"] = 1;
if (!$conf["list_readme"])
continue;
}
$lvar["flist"][] = $fn;
}
closedir($handle);
}
else
$this->error("could_not_open", ' "'.$lvar["path"].'"');
// now sort the list according to the config
$lvar["flist"] = $this->sort_flist($lvar["flist"], $lvar["path"]);
if (!$lvar["error"]) {
// do title links
$lvar["content"] .= '<h1 class="'.
$this->pi_getClassName("title").
'">';
$lvar["content"] .= htmlspecialchars($this->pi_getLL("listing")).' ';
// ==================================================
// EDIT 26.07.2005 by TK //
// $lvar["content"] ausgeklammert (realpath soll nicht angezeigt werden)
// for ($i=1 geaendert ind for ($i=2
// ==================================================
//$lvar["content"] .= $lvar["title_path_link"][0].'/';
for ($i=2; $i<count($lvar["title_path_link"]); $i++) {
// ==================================================
// EDIT 26.07.2005 by TK //
// ==================================================
$lvar["content"] .= $this->pi_linkTP(
$lvar["title_path_link"][$i][0],
array($conf["url_var_path"] =>
$lvar["title_path_link"][$i][1]));
$lvar["content"] .= '/';
}
$lvar["content"] .= '</h1>';
// display a readme file?
if ($lvar["readme_found"]) {
if (!@is_readable($lvar["path"].$conf["readme_file"]))
$this->error("could_not_open", $conf["readme_file"]);
else
$lvar["content"] .= '<pre>'.
implode("", file($lvar["path"].$conf["readme_file"])).
'</pre>';
}
// prepare table
$lvar["content"] .= '<table width="100%" border="0"'.
' cellspacing="0" cellpadding="5">';
$lvar["content"] .= '<tr class="'.
$this->pi_getClassName("header-row").
'">';
$lvar["content"] .= '<td class="'.
$this->pi_getClassName("header-icon").
'"> </td>';
$lvar["content"] .= '<td class="'.
$this->pi_getClassName("header-filename").'">'.
htmlspecialchars($this->pi_getLL("filename")).
'</td>';
if ($conf["show_permissions"])
$lvar["content"] .= '<td class="'.
$this->pi_getClassName("header-perms").'">'.
htmlspecialchars($this->pi_getLL("perms")).
'</td>';
if ($conf["show_owner"])
$lvar["content"] .= '<td class="'.
$this->pi_getClassName("header-owner").'">'.
htmlspecialchars($this->pi_getLL("owner")).
'</td>';
if ($conf["show_group"])
$lvar["content"] .= '<td class="'.
$this->pi_getClassName("header-group").'">'.
htmlspecialchars($this->pi_getLL("group")).
'</td>';
if ($conf["show_filesize"])
$lvar["content"] .= '<td class="'.
$this->pi_getClassName("header-filesize").'">'.
htmlspecialchars($this->pi_getLL("filesize")).
'</td>';
if ($conf["show_filemod"])
$lvar["content"] .= '<td class="'.
$this->pi_getClassName("header-filemod").'">'.
htmlspecialchars($this->pi_getLL("filemod")).
'</td>';
$lvar["content"] .= $this->list_files($lvar["flist"],
$lvar["path_to_rep"], $lvar["path_in_rep"]);
$lvar["content"] .= '</tr>';
$lvar["content"] .= '</table>';
}
// debugging info
//t3lib_div::debug($conf);
//t3lib_div::debug($this->lvar);
return $this->pi_wrapInBaseClass($lvar["content"]);
}
/**
* error output function
*/
function error($str, $param="") {
$this->lvar["error"] = 1;
$this->lvar["content"] .= '<span class="'.
$this->pi_getClassName("error").'">'.
htmlspecialchars($this->pi_getLL("error")).
': '.htmlspecialchars($this->pi_getLL($str)).
$param.
'</span><br>';
}
/**
* return unix style permission (drwxrwxrwx)
* taken from Andreas' script (see header)
*/
function unix_perms($mode) {
/* Determine Type */
if( $mode & 0x1000 ) $type='p'; /* FIFO pipe */
elseif( $mode & 0x2000 ) $type='c'; /* Character special */
elseif( $mode & 0x4000 ) $type='d'; /* Directory */
elseif( $mode & 0x6000 ) $type='b'; /* Block special */
elseif( $mode & 0x8000 ) $type='-'; /* Regular */
elseif( $mode & 0xA000 ) $type='l'; /* Symbolic Link */
elseif( $mode & 0xC000 ) $type='s'; /* Socket */
else $type='u'; /* UNKNOWN */
/* Determine permissions */
$owner["read"] = ($mode & 00400) ? 'r' : '-';
$owner["write"] = ($mode & 00200) ? 'w' : '-';
$owner["execute"] = ($mode & 00100) ? 'x' : '-';
$group["read"] = ($mode & 00040) ? 'r' : '-';
$group["write"] = ($mode & 00020) ? 'w' : '-';
$group["execute"] = ($mode & 00010) ? 'x' : '-';
$world["read"] = ($mode & 00004) ? 'r' : '-';
$world["write"] = ($mode & 00002) ? 'w' : '-';
$world["execute"] = ($mode & 00001) ? 'x' : '-';
/* Adjust for SUID, SGID and sticky bit */
if( $mode & 0x800 )
$owner["execute"] = ($owner[execute]=='x') ? 's' : 'S';
if( $mode & 0x400 )
$group["execute"] = ($group[execute]=='x') ? 's' : 'S';
if( $mode & 0x200 )
$world["execute"] = ($world[execute]=='x') ? 't' : 'T';
return
$type.
$owner["read"].$owner["write"].$owner["execute"].
$group["read"].$group["write"].$group["execute"].
$world["read"].$world["write"].$world["execute"];
}
/**
* return the type for $fn
* file type depends on the file extension
*/
function type_from_file($fn) {
foreach($this->conf["map_type_to_ext."] as $type => $ext) {
$ext = explode("|", $ext);
for ($i=0; $i<count($ext); $i++) {
$ext[$i] = str_replace(".", "\.", $ext[$i]);
$ext[$i] = str_replace("+", "\+", $ext[$i]);
if (eregi($ext[$i].'$', $fn))
return $type;
}
}
return "unknown";
}
/**
* return the icon for $type
*/
function icon_from_type($type) {
if (array_key_exists($type, $this->conf["map_type_to_icon."]))
return $this->conf["map_type_to_icon."][$type];
else
return $this->icon_from_type("unknown");
}
/**
* sort the list of files and return it
*/
function sort_flist($flist, $path) {
$a_dirs = $a_files = array();
if ($this->conf["folders_top"]) {
for($i=0; $i<count($flist); $i++) {
if (@is_dir($path.$flist[$i]))
$a_dirs[] = $flist[$i];
else
$a_files[] = $flist[$i];
}
}
else {
$a_files = $flist;
}
// define callback functions
if ($this->conf["nat_sorting"] && $this->conf["case_sorting"])
$cmp = "strnatcmp";
elseif ($this->conf["nat_sorting"] && !$this->conf["case_sorting"])
$cmp = "strnatcasecmp";
elseif (!$this->conf["nat_sorting"] &&$this->conf["case_sorting"])
$cmp = "strcmp";
elseif(!$this->conf["cat_sorting"] && !$this->conf["case_sorting"])
$cmp = "strcasecmp";
usort($a_dirs, $cmp);
usort($a_files, $cmp);
return array_merge($a_dirs, $a_files);
}
/**
* return filesize in human readable format
*/
function fsize($fn) {
$sizetags = array("B", "KB", "MB", "GB", "TB");
$filesize = @filesize($fn);
for ($i=0; $i<count($sizetags); $i++)
if ($filesize >= 1024)
$filesize /= 1024;
else
break;
return ceil($filesize).' '.$sizetags[$i];
}
/**
* create the listing table, returns a html string
* $a_files is an array with all the files to list, filenames
* relative to the starting point of the repository
*/
function list_files($flist, $path_to_rep, $path_in_rep) {
$content = "";
$path = $path_to_rep.$path_in_rep;
//### with one of the two is safe?
$iconpath = dirname($this->conf["includeLibs"]).'/icons/';
$iconpath .= $this->conf["icons_theme"].'/';
$beauty = 0;
foreach($flist as $fn) {
// choose the right icon
$type = $this->type_from_file($fn);
$iconfile = $this->icon_from_type($type);
if (@is_dir($path.$fn)) {
if (strcmp($fn, "..") == 0)
$iconfile = $this->icon_from_type("move_up");
else
$iconfile = $this->icon_from_type("folder");
}
if (!@is_readable($path.$fn)) {
if (!$this->conf["list_unreadable"])
continue;
if (@is_dir($path.$fn))
$iconfile = $this->icon_from_type("folder_denied");
else
$iconfile = $this->icon_from_type("file_denied");
}
// enable links to source code beautifier?
if ($this->conf["asb_id"] >= 0) {
if (in_array($type, explode(",", $this->conf["beauty_types"])))
$beauty = 1;
else
$beauty = 0;
}
// we are ready for output!
$content .= '<tr class="'.$this->pi_getClassName("row").'">';
// display icon
$content .= '<td class="'.$this->pi_getClassName("icon").'">';
$content .= '<img src="'.$iconpath.$iconfile.'">';
$content .= '</td>';
// name
if (@is_dir($path.$fn)) {
if (strcmp($fn, "..") == 0)
$link = dirname($path_in_rep);
else
$link = $path_in_rep.$fn;
$content .= '<td class="'.$this->pi_getClassName("filename").'">';
$content .= '<b>[';
$content .= $this->pi_linkTP($fn,
array($this->conf["url_var_path"] => $link));
$content .= ']</b>';
$content .= '</td>';
}
else {
if ($beauty) {
$content .= '<td class="'.
$this->pi_getClassName("filename-asb").
'">';
$content .= '<a href="'.
$this->pi_getPageLink($this->conf["asb_id"]).
'?'.
$this->conf["asb_url_var_path"].
'='.
urlencode($path_in_rep.$fn).
'">'.$fn.'</a>';
$content .= ' (<a href="'.$path.$fn.'">'.
$this->pi_getLL("orig").
'</a>)';
$content .= '</td>';
}
// ==================================================
// EDIT 14.07.2005 by TK //
// ==================================================
else {
$content .= '<td class="'.$this->pi_getClassName("filename").'">';
$content .= '<a href="/loader.php?ID=';
$encode = $path. $fn;
$encode = base64_encode(($encode));
$encode = asc2hex($encode);
$content .= $encode;
$content .= '">'. $fn. '</a></td>';
// ==================================================
// EDIT 14.07.2005 by TK //
// ==================================================
}
}
// permissions
if ($this->conf["show_permissions"]) {
$content .= '<td class="'.$this->pi_getClassName("perms").'">';
$content .= '<pre>';
$content .= $this->unix_perms(@fileperms($path.$fn));
$content .= '</pre>';
$content .= '</td>';
}
// owner
if ($this->conf["show_owner"]) {
$owneruid = @fileowner($path.$fn);
$owner = @posix_getpwuid($owneruid);
$content .= '<td class="'.$this->pi_getClassName("owner").'">';
$content .= $owner["name"] ? $owner["name"] : $owneruid;
$content .= '</td>';
}
// group
if ($this->conf["show_group"]) {
$groupgid = @filegroup($path.$fn);
$group = @posix_getgrgid($groupgid);
$content .= '<td class="'.$this->pi_getClassName("group").'">';
$content .= $group["name"] ? $group["name"] : $groupgid;
$content .= '</td>';
}
// filesize
// ==================================================
// EDIT 14.07.2005 by TK //
// ==================================================
if ($this->conf["show_filesize"]) {
if (!@is_dir($path.$fn)) {
$content .= '<td class="'.$this->pi_getClassName("filesize").'">';
$content .= $this->fsize($path.$fn);
$content .= '</td>';
}
else
{
$content .= '<td></td>';
}
// ==================================================
// EDIT 14.07.2005 by TK //
// ==================================================
}
// last modification
if ($this->conf["show_filemod"]) {
$content .= '<td class="'.$this->pi_getClassName("filemod").'">';
$content .= @date($this->conf["date_format"], @filemtime($path.$fn));
$content .= '</td>';
}
$content .= '</tr>';
}
return $content;
}
}
if (defined("TYPO3_MODE") && $TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/dir_listing/pi1/class.tx_dirlisting_pi1.php"]) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/dir_listing/pi1/class.tx_dirlisting_pi1.php"]);
}
// ==================================================
// EDIT 15.07.2005 by TK //
// ==================================================
function asc2hex($temp) {
$len = strlen($temp);
for ($i=0; $i<$len; $i++) $data.=sprintf("%02x",ord(substr($temp,$i,1)));
return $data;
}
// ==================================================
// EDIT 14.07.2005 by TK //
// ==================================================
?> File: loader.php (im webroot)
Code:
<?php
$filename = $_GET['ID'];// your parameter
if ($filename == '')
{
die("No Parameter");
};
$filename = hex2asc($filename);
$filename = base64_decode(($filename));
$filename = ("/mnt/sdb1/www/web/webroot/". $filename); //server specific
$file_extension = strtolower(substr(strrchr($filename,"."),1));
if (! file_exists($filename) )
{
die("Error! Please contact Site Administrator...");
};
switch( $file_extension )
{
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "doc": $ctype="application/msword"; break;
case "xls": $ctype="application/vnd.ms-excel"; break;
case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpe": case "jpeg":
case "jpg": $ctype="image/jpg"; break;
default: $ctype="application/force-download";
}
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers
header("Content-Type: $ctype");
header("content-disposition: attachment; filename=".basename($filename).";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".@filesize($filename));
@readfile("$filename") or die("File not found.");
exit();
function hex2asc($temp) {
$len = strlen($temp);
for ($i=0;$i<$len;$i+=2) $data.=chr(hexdec(substr($temp,$i,2)));
return $data;
}
?> wichtig ist im loaderfile den richtigen festen Pfad anzugeben. Eventuell sollte man vielleicht noch die Variablen filtern, damit niemand auf andere Dateien in Deinem Webspace zugreifen kann (SICHERHEITSLECK!!!)
aber als Basis sollte Dir das schonmal weiterhelfen
greets, Ted