Log in

View Full Version : My directory listing script.. Do you like?



hmsnacker123
01-23-2009, 08:04 PM
Hey everyone, ive been writing this script over the last few days, I just wanted to hear what you thought of it. ::


<?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 .= ' -&gt; ' . 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>';
?>