<?
/*
    PHP Download
    Copyright 2004 Stepan Riha
    All Rights Reserved

    http://www.nonplus.net

    Free for non-commercial use.

    Version 1.0 - 9/28/2004
*/

## BEGIN CONFIG

    // PASSWORD
    
$cfg_password "";

    
// BASE DIRECTORY (default ".")
    
$cfg_basedir ".";

## END CONFIG

    
session_start();

    
$message '';
    if(
$_REQUEST['login']) {
        
$_SESSION['pwd'] = crypt($_REQUEST['password'], md5(rand() . time()));
    } elseif(
$_REQUEST['logout']) {
        
$_SESSION['pwd'] = '';
    } 

    
$pwd $_SESSION['pwd'];
    
$logged_in $pwd == crypt($cfg_password$pwd);

    
// Sanity checking
    
if(!$cfg_password)
        
$message .= "<b>PASSWORD</b> not configured!<br />";
    if(!
$cfg_basedir)
        
$message .= "<b>BASE DIRECTORY</b> not configured!<br />";

    
$cfg_basedir realpath($cfg_basedir);

    if(
$message) {
        
$logged_in false;
        unset(
$_REQUEST['login']);
    }

    if(
$_REQUEST['login'] && !$logged_in)
        
$message "Invalid password!";

    if(
$logged_in) {
        if(
$_REQUEST["download"] != '') {
            
$path $_REQUEST["download"];
            if(
substr($path0strlen($cfg_basedir)) == $cfg_basedir
                    
&& file_exists($path)
                    && (
filetype($path) == 'file' || filetype($path) == 'dir'))
                
download_file($path);
            else
                
$message"Invalid download: $path, exists: " file_exists($path);
        }

        
$dir realpath($_REQUEST['dir']);
        if(!
$dir || (substr($dir0strlen($cfg_basedir)) != $cfg_basedir))
            
$dir $cfg_basedir;
    }

//=========================================================================
// download_file:
// Tar, gzip and download specified path
//=========================================================================
function download_file($path) {
    
header("Content-type: application/x-gzip");
    
header("Content-Disposition: attachment; filename=" basename($path) . ".tgz");
    
$dir dirname($path);
    
$file basename($path);
    
passthru("tar -zcf - -C '$dir' '$file'");
    exit;
}

//=========================================================================
// file_cmp:
// Compare to files based on type and name (case insensitive)
//=========================================================================
function file_cmp($a$b) {

    
// Compare by file type (dir < file)
    
$cmp strcmp($a['type'], $b['type']);
    if(
$cmp)
        return 
$cmp;

    
// Compare case-insensitive
    
$cmp strcasecmp($a['name'], $b['name']);
    if(
$cmp)
        return 
$cmp;

    
// Compare case-sensitive
    
$cmp strcmp($a['name'], $b['name']);
    if(
$cmp)
        return 
$cmp;

    return 
0;
}

//=========================================================================
// read_directory:
// Return contents of directory as array of file descriptors
//=========================================================================
function read_directory($dir) {
    
$files = array();
    if (
is_dir($dir)) {
        if (
$dh opendir($dir)) {
            while ((
$file readdir($dh)) !== false) {
                
$path "$dir/$file";
                
$type filetype($path);
                
$size = ($type == 'file') ? $size filesize($path) . ' bytes' '';

                
$files[] = array('name' => $file'type' => $type'size' => $size'path' => $path);
           }
           
closedir($dh);
       }
    }
    
usort($files'file_cmp');
    return 
$files;
}
?>

<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>PHP Download: <?=$dir?></title>
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">

<style type="text/css">
<!-- 
body {
margin: 0;
font-family: 'Trebuchet MS', Verdana, sans-serif;
}

body, p, td, div {
font-size: 12px;
}

 td.header {
background: #eec;
border-bottom: #dda 1px solid;
padding: 10px 15px 10px 15px;
}

td.content {
padding: 15px;
vertical-align: top;
}

td.footer {
border-top: #dda 1px solid;
background: #eec;
padding: 4px 15px 4px 15px;
}


td.header td {
padding: 0;
}

td {
    padding: 0px 5px 0px 5px;
}

.header td h1 {
margin: 0;
font-size: 20px;
}

h2 {
font-size: 16px;
}

div.message {
    margin: 5px 5px 15px 5px;
    padding: 10px;
    background: #eee;
    border: solid 1px #ddd;
}

tr.row1 td {
background: #def;
}

-->
</style>

</head>

<body>

<table cellpadding="0" cellspacing="0" width="100%" height="100%">
<tbody>
<tr class="header">
<td nowrap class="header">

<table cellpadding="0" cellspacing="0" width="100%" height="100%">
<tbody>
<tr>
<td nowrap><h1>PHP Download</h1></td>
<td align="right">
<? if($logged_in) : ?>
<a href="?logout=1">Log out</a>
<? endif; ?>
</td>
</tr>
</tbody>
</table>

</td>
</tr>

<tr class="content" height="100%">
<td width="100%" height="100%" class="content">

<? if($message) : ?>
<div class="message"><?=$message?></div>
<? endif; ?>

<? if($logged_in) :

    
$files read_directory($dir);

    
$trail explode('/'substr($dirstrlen(dirname($cfg_basedir))));

    print 
"<h2>" dirname($cfg_basedir);
    
$path dirname($cfg_basedir);
    
$count 0;
    foreach(
$trail as $segment) {
        
$path .= "$segment";
        if(++
$count count($trail))
            print 
"<a href=\"?dir=$path\">$segment</a>/";
        else
            print 
"$segment";
        
$path .= "/";
    }
    print 
"</h2>";
?>

<table cellpadding="0" cellspacing="0"  width="100%">
<tbody>
<tr>

<!-- Directories -->
<td valign="top" width="50%">
<table cellpadding="0" cellspacing="0"  width="100%">
<tbody>
<tr>
<th colspan="2">Directories</th>
</tr>
<?
$count 
0;
foreach(
$files as $f) {
    
$type $f['type'];
    
$file $f['name'];
    if(
$type != 'dir' || $file == '..')
        continue;

    
$count++;
    
$row $count 2;
    
$size $f['size'];
    
$path realpath("$dir/$file");
    if(
$file == '.') {
        
$file basename($path);
        
$name "Current directory (<b>$file</b>)";
        echo
<<<LINE
<tr class="row$row">
<td width="100%">Current directory (<b>$file</b>)</td><td><a href="?download=$path" title="Download directory '$path'">Download</a></td>
</tr>
LINE;
    } else {
        
$name $file;
        echo
<<<LINE
<tr class="row$row">
<td width="100%"><a href="?dir=$path">$name</a></td><td><a href="?download=$path" title="Download directory '$path'">Download</a></td>
</tr>
LINE;
    }
}

?>
</tbody>
</table>

</td>



<!-- Files -->
<td valign="top" width="50%">

<table cellpadding="0" cellspacing="0"  width="100%">
<tbody>
<tr>
<th colspan="3">Files</th>
</tr>
<?
//  passthru("ls $cfg_basedir");

// Open a known directory, and proceed to read its contents
$count 0;
foreach(
$files as $f) {
    
$type $f['type'];
    if(
$type != 'file')
        continue;
    
$file $f['name'];
    
$size $f['size'];
    
$path realpath("$dir/$file");
    if(
$file == '.')
        
$name 'This Directory';
    elseif(
$file == '..')
        
$name 'Parent Directory';
    else
        
$name $file;
    
$count++;
    
$row $count 2;
    echo
<<<LINE
<tr class="row$row">
<td width="100%">$name</td><td align="right" nowrap>$size</td><td><a href="?download=$path" title="Download file '$path'">Download</a></td>
</tr>
LINE;
}

?>
</tbody>
</table>

</td>

</tr>
</tbody>
</table>
<? else : ?>
<form method=post action="">

<table cellpadding="0" cellspacing="0" width="100%" height="100%">
<tbody>
<tr><td>Password:</td><td width="100%"><input type="password" name="password"></td></tr>
<tr><td>&nbsp;</td><td><br /><input type="submit" value="Log In" name="login"></td></tr>
</tbody>
</table>

</form>
<? endif; ?>

</td>
</tr>

<tr class="footer">
<td nowrap class="footer">&copy 2004 <a href="http://www.nonplus.net/">Stepan Riha</a></td>
</tr>

</tbody>
</table>

</body>
</html>