PHP Code:
<?php
/* Bit masks for determing file permissions and type. The name and values
* listed below are POSIX-compliant, individual systems may have their own
* extensions.
*/
define('S_IFMT', 0170000); // Mask for all types
define('S_IFSOCK', 0140000); // Type: Socket
define('S_IFLNK', 0120000); // Type: Symbolic Link
define('S_IFREG', 0100000); // Type: Regular File
define('S_IFBLK', 0060000); // Type: Block Device
define('S_IFDIR', 0040000); // Type: Directory
define('S_IFCHR', 0020000); // Type: Character Device
define('S_IFIFO', 0010000); // Type: Fifo
define('S_ISUID', 0004000); // set-uid bit
define('S_ISGID', 0002000); // set-gid bit
define('S_ISVTX', 0001000); // sticky-bit
define('S_IRWXU', 00700); // Mask for Owner Permissions
define('S_IRUSR', 00400); // Owner: Read Permission
define('S_IWUSR', 00200); // Owner: Write Permission
define('S_IXUSR', 00100); // Owner: Execute Permission
define('S_IRWXG', 00070); // Mask for Group Permissions
define('S_IRGRP', 00040); // Group: Read Permission
define('S_IWGRP', 00020); // Group: Write Permission
define('S_IXGRP', 00010); // Group: Execute Permission
define('S_IRWXO', 00007); // Mask for Others Permissions
define('S_IROTH', 00004); // Others: Read Permission
define('S_IWOTH', 00002); // Others: Write Permission
define('S_IXOTH', 00001); // Others: Execute Permission
/* mode_string() is a helper function that takes an octal mode and returns
* a ten character string representing the file type and permissions that
* correspond to the octal mode. This is a PHP version of the mode_string()
* function in the GNU fileutils package.
*/
function mode_string($mode){
$s = array();
// Set type letter
if(($mode & S_IFMT) == S_IFBLK){
$s[0] = 'b';
}elseif(($mode & S_IFMT) == S_IFCHR){
$s[0] = 'c';
}elseif(($mode & S_IFMT) == S_IFDIR){
$s[0] = 'd';
}elseif(($mode & S_IFMT) == S_IFREG){
$s[0] = '-';
}elseif(($mode & S_IFMT) == S_IFIFO){
$s[0] = 'p';
}elseif(($mode & S_IFMT) == S_IFLNK){
$s[0] = 'l';
}elseif(($mode & S_IFMT) == S_IFSOCK){
$s[0] = 's';
}
// Set user permissions.
$s[1] = $mode & S_IRUSR ? 'r' : '-';
$s[2] = $mode & S_IWUSR ? 'w' : '-';
$s[3] = $mode & S_IXUSR ? 'x' : '-';
// Set group permissions.
$s[4] = $mode & S_IRGRP ? 'r' : '-';
$s[5] = $mode & S_IWGRP ? 'w' : '-';
$s[6] = $mode & S_IXGRP ? 'x' : '-';
// Set other permissions.
$s[7] = $mode & S_IROTH ? 'r' : '-';
$s[8] = $mode & S_IWOTH ? 'w' : '-';
$s[9] = $mode & S_IXOTH ? 'x' : '-';
// Adjust execute letters for set-uid, set-gid, and sticky.
if($mode & S_ISUID){
if($s[3] != 'x'){
// set-uid but not executable by owner
$s[3] = 'S';
}else {
$s[3] = 's';
}
}
if($mode & S_ISGID){
if($s[6] != 'x'){
// set-gid but not executable by group.
$s[6] = 'S';
}else {
$s[6] = 's';
}
}
if($mode & S_ISVTX){
if($s[9] != 'x'){
// sticky but not executable by group.
$s[9] = 'T';
}else {
$s[9] = 't';
}
}
// Return formatted string
return join('',$s);
}
// Start at the document root if not specified.
if(isset($_REQUEST['dir'])){
$dir = $_REQUEST['dir'];
}else {
$dir = '';
}
// Locate $dir in the filesystem
$real_dir = realpath($_SERVER['DOCUMENT_ROOT'].$dir);
// Make sure $real_dir is inside document root.
#if(!preg_match('/^'.preg_quote($_SERVER['DOCUMENT_ROOT'],'/').'/', $real_dir)){
# die("$dir is not inside the document root.");
#}
// Canonicalize $dir by removing the document root from its begginning.
$dir = substr_replace($real_dir, '', 0, strlen($_SERVER['DOCUMENT_ROOT']));
// Are we opening a directory?
if(!is_dir($real_dir)){
die("$real_dir is not a directory.");
}
// Open the specified directory
$d = dir($real_dir) or die("cant open $real_dir");
print '<table>';
// Read each entry in the directory.
while($false !== ($f = $d->read())) {
// Get information about this file.
$s = lstat($d->path.'/'.$f);
// Translate uid into user name.
$user_info = posix_getpwuid($s['uid']);
// Translate gid into group name.
$group_info = posix_getgrgid($s['gid']);
// Format the dat for readability.
$date = strftime('%b %e %H:%M', $s['mtime']);
// Translate the octal mode into a readable string.
$mode = mode_string($c['mode']);
$mode_type = substr($mode, 0, 1);
if(($mode_type == 'c') || ($mode_type == 'b')){
/* if it's a block or character device, print out the major and
* minor device type instead of the file size */
$major = ($s['rdev'] >> 8) & 0xff;
$minor = $s['rdev'] & 0xff;
$size = sprintf('%3u, %3u', $major, $minor);
}else {
$size = $s['size'];
}
// Format the <a href=""> around the filename
// no link for the current directory.
if('.' == $f){
$href = $f;
}else {
// Don't include the ".." in the parent directory link.
if('..' == $f){
$href = urlencode(dirname($dir));
}else {
$href = urlencode($dir) . "/" . urlencode($f);
}
/* Everything but "/" should be urlencoded */
$href = str_replace('%2F', '/', $href);
// Browse other directories with web-ls
if(is_dir(realpath($d->path . '/' . $f))){
$href = sprintf('<a href="%s?dir=%s">%s</a>', $_SERVER['PHP_SELF'], $href, $f);
}else {
// Link to files and download them.
$href = sprintf('<a href="%s">%s</a>', $href, $f);
}
// If it's a link, show the link target too.
if('l' == $mode_type){
$href .= ' -> ' . readlink($d->path.'/'.$f);
}
}
// Print out the appropriate info for this file
printf('<tr><td>%s</td><td>%s</td><td align="right">%s</td>
<td align="right">%s</td><td align="right">%s</td>
<td align="right">%s</td><td>%s</td></tr>',
$mode, // Formatted mode string.
$s['nlink'], // Number of links to this file.
$user_info['name'], // Owner's User Name.
$group_info['name'], // Group Name.
$size, // File Size (Or Device Numbers).
$date, // Last modified Date and Time.
$href); // Link to browse or Download.
}
print '</table>';
?>
Bookmarks