1
0
mirror of https://github.com/misterunknown/ifm.git synced 2025-08-11 02:24:00 +02:00

Merge pull request #30 from misterunknown/issue-26

Issue 26
This commit is contained in:
Marco Dickert
2017-03-20 12:45:43 +01:00
committed by GitHub
4 changed files with 142 additions and 66 deletions

104
ifm.php
View File

@@ -34,14 +34,40 @@ class IFMConfig {
const showfilesize = 1; // show filesize?
const showowner = 1; // show file owner?
const showgroup = 1; // show file group?
const showpath = 0; // show real path of directory (not only root)?
const showpermissions = 2; // show permissions 0 -> not; 1 -> octal, 2 -> human readable
const showhtdocs = 1; // show .htaccess and .htpasswd
const showhiddenfiles = 1; // show files beginning with a dot (e.g. ".bashrc")
const showpath = 0; // show absolute path
// general config
/*
authentication
This provides a super simple authentication functionality. At the moment only one user can be
configured. The credential information can be either set inline or read from a file. The
password has to be a hash generated by PHPs password_hash function. The default credentials are
admin:admin.
If you specify a file it should only contain one line, with the credentials in the following
format:
<username>:<passwordhash>
examples:
const auth_source = 'inline;admin:$2y$10$0Bnm5L4wKFHRxJgNq.oZv.v7yXhkJZQvinJYR2p6X1zPvzyDRUVRC';
const auth_source = 'file;/path/to/file';
*/
const auth = 0;
const auth_source = 'inline;admin:$2y$10$0Bnm5L4wKFHRxJgNq.oZv.v7yXhkJZQvinJYR2p6X1zPvzyDRUVRC';
/*
root_dir - set a custom root directory instead of the script location
This option is highly experimental and should only be set if you definitely know what you do.
Settings this option may cause black holes or other unwanted things. Use with special care.
default setting:
const root_dir = "";
*/
const root_dir = "";
const defaulttimezone = "Europe/Berlin"; // set default timezone
// development tools
@@ -350,7 +376,7 @@ div.footer div.panel-body { padding: 5px !important; }
<div class="form-group">
<div class="input-group">
<span class="input-group-addon" id="currentDirLabel">Content of <span id="docroot">';
if( IFMConfig::showpath == 1 ) print $this->getScriptRoot().'/'; else print '/';
print ( IFMConfig::showpath == 1 ) ? realpath( IFMConfig::root_dir ) : "/";
print '</span></span><input class="form-control" id="currentDir" aria-describedby="currentDirLabel" type="text">
</div>
</div>
@@ -440,6 +466,7 @@ function IFM() {
this.IFM_SCFN = "<?=basename($_SERVER['SCRIPT_NAME'])?>";
this.config = jQuery.parseJSON('<?php echo json_encode(IFMConfig::getConstants()); ?>'); // serialize the PHP config array, so we can use it in JS too
this.isDocroot = <?php echo realpath( IFMConfig::root_dir ) == dirname( __FILE__ ) ? "true" : "false"; ?>;
this.editor = null; // global ace editor
this.fileChanged = false; // flag for check if file was changed already
this.currentDir = ""; // this is the global variable for the current directory; it is used for AJAX requests
@@ -497,16 +524,20 @@ function IFM() {
else if( self.config.edit == 1 && data[i].name.toLowerCase().substr(-4) != ".zip" )
newRow += ' data-eaction="edit"';
newRow += '><td><a tabindex="0"';
var guid = self.generateGuid();
if(data[i].type=="file") {
newRow += ' href="'+self.pathCombine(ifm.currentDir,data[i].name)+'"';
if( data[i].icon.indexOf( 'file-image' ) !== -1 )
newRow += ' data-toggle="tooltip" title="<img src=\''+self.pathCombine(self.currentDir,data[i].name)+'\' class=\'imgpreview\'>"';
if( self.isDocroot ) {
newRow += ' href="'+self.pathCombine(ifm.currentDir,data[i].name)+'"';
if( data[i].icon.indexOf( 'file-image' ) !== -1 )
newRow += ' data-toggle="tooltip" title="<img src=\''+self.pathCombine(self.currentDir,data[i].name)+'\' class=\'imgpreview\'"';
} else {
newRow += ' onclick="$(\'#d_'+guid+'\').submit();"';
}
} else {
newRow += ' onclick="ifm.changeDirectory(\''+data[i].name+'\')"';
}
newRow += '><span class="'+data[i].icon+'"></span> ' + ( data[i].name == '..' ? '[ up ]' : data[i].name ) + '</a></td>';
if( ( data[i].type != "dir" && self.config.download == 1 ) || ( data[i].type == "dir" && self.config.zipnload == 1 ) ) {
var guid = self.generateGuid();
newRow += '<td><form id="d_' + guid + '">';
newRow += '<input type="hidden" name="dir" value="' + self.currentDir + '">';
newRow += '<input type="hidden" name="filename" value="' + ( data[i].name == '..' ? '.' : data[i].name ) + '">';
@@ -1287,9 +1318,9 @@ ifm.init();
private function handleRequest() {
if($_REQUEST["api"] == "getRealpath") {
if( isset( $_REQUEST["dir"] ) && $_REQUEST["dir"] != "" )
$this->getRealpath( $_REQUEST["dir"] );
echo json_encode( array( "realpath" => $this->getValidDir( $_REQUEST["dir"] ) ) );
else
echo json_encode(array("realpath"=>""));
echo json_encode( array( "realpath" => "" ) );
}
elseif( $_REQUEST["api"] == "getFiles" ) {
if( isset( $_REQUEST["dir"] ) && $this->isPathValid( $_REQUEST["dir"] ) )
@@ -1321,6 +1352,11 @@ ifm.init();
public function run() {
if ( $this->checkAuth() ) {
// go to our root_dir
if( ! is_dir( realpath( IFMConfig::root_dir ) ) || ! is_readable( realpath( IFMConfig::root_dir ) ) )
die( "Cannot access root_dir.");
else
chdir( IFMConfig::root_dir );
if ( ! isset($_REQUEST['api']) ) {
$this->getApplication();
} else {
@@ -1831,14 +1867,6 @@ ifm.init();
</html>';
}
private function getValidDir($dir) {
if( $this->getScriptRoot() != substr( realpath( $dir ), 0, strlen( $this->getScriptRoot() ) ) ) {
return "";
} else {
return ( file_exists( realpath( $dir ) ) ) ? substr( realpath( $dir ), strlen( $this->getScriptRoot() ) + 1 ) : "";
}
}
private function filePermsDecode( $perms ) {
$oct = str_split( strrev( decoct( $perms ) ), 1 );
$masks = array( '---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx' );
@@ -1851,17 +1879,36 @@ ifm.init();
);
}
private function isPathValid($p) {
if( $p == "" ) {
return true;
} elseif( str_replace( "\\", "/", $this->getScriptRoot() ) == str_replace( "\\", "/", substr( realpath( dirname( $p ) ), 0, strlen( $this->getScriptRoot() ) ) ) ) {
return true;
private function getValidDir( $dir ) {
if( ! $this->isPathValid( $dir ) || ! is_dir( $dir ) ) {
return "";
} else {
$rpDir = realpath( $dir );
$rpConfig = realpath( IFMConfig::root_dir );
if( $rpConfig == "/" )
return $rpDir;
elseif( $rpDir == $rpConfig )
return "";
else
return substr( $rpDir, strlen( $rpConfig ) + 1 );
}
return false;
}
private function isPathValid( $dir ) {
$rpDir = realpath( $dir );
$rpConfig = realpath( IFMConfig::root_dir );
if( ! is_string( $rpDir ) || ! is_string( $rpConfig ) ) // can happen if open_basedir is in effect
return false;
elseif( $rpDir == $rpConfig )
return true;
elseif( 0 === strpos( $rpDir, $rpConfig ) ) {
return true;
}
else
return false;
}
private function getScriptRoot() {
//return realpath( substr( $_SERVER["SCRIPT_FILENAME"], 0, strrpos( $_SERVER["SCRIPT_FILENAME"], "/" ) ) );
return dirname( $_SERVER["SCRIPT_FILENAME"] );
}
@@ -1886,15 +1933,6 @@ ifm.init();
}
}
private function getRealpath($dir) {
if( $this->getScriptRoot() != substr( realpath( $_POST["dir"] ), 0, strlen( $this->getScriptRoot() ) ) ) {
echo json_encode( array( "realpath" => "" ) );
} else {
$rp = substr( realpath( $_POST["dir"] ), strlen( $this->getScriptRoot() ) + 1 );
if( $rp == false ) $rp = "";
echo json_encode( array( "realpath" => $rp ) );
}
}
private function rec_rmdir( $path ) {
if( !is_dir( $path ) ) {
return -1;

View File

@@ -34,14 +34,40 @@ class IFMConfig {
const showfilesize = 1; // show filesize?
const showowner = 1; // show file owner?
const showgroup = 1; // show file group?
const showpath = 0; // show real path of directory (not only root)?
const showpermissions = 2; // show permissions 0 -> not; 1 -> octal, 2 -> human readable
const showhtdocs = 1; // show .htaccess and .htpasswd
const showhiddenfiles = 1; // show files beginning with a dot (e.g. ".bashrc")
const showpath = 0; // show absolute path
// general config
/*
authentication
This provides a super simple authentication functionality. At the moment only one user can be
configured. The credential information can be either set inline or read from a file. The
password has to be a hash generated by PHPs password_hash function. The default credentials are
admin:admin.
If you specify a file it should only contain one line, with the credentials in the following
format:
<username>:<passwordhash>
examples:
const auth_source = 'inline;admin:$2y$10$0Bnm5L4wKFHRxJgNq.oZv.v7yXhkJZQvinJYR2p6X1zPvzyDRUVRC';
const auth_source = 'file;/path/to/file';
*/
const auth = 0;
const auth_source = 'inline;admin:$2y$10$0Bnm5L4wKFHRxJgNq.oZv.v7yXhkJZQvinJYR2p6X1zPvzyDRUVRC';
/*
root_dir - set a custom root directory instead of the script location
This option is highly experimental and should only be set if you definitely know what you do.
Settings this option may cause black holes or other unwanted things. Use with special care.
default setting:
const root_dir = "";
*/
const root_dir = "";
const defaulttimezone = "Europe/Berlin"; // set default timezone
// development tools

View File

@@ -5,6 +5,7 @@ function IFM() {
this.IFM_SCFN = "<?=basename($_SERVER['SCRIPT_NAME'])?>";
this.config = jQuery.parseJSON('<?php echo json_encode(IFMConfig::getConstants()); ?>'); // serialize the PHP config array, so we can use it in JS too
this.isDocroot = <?php echo realpath( IFMConfig::root_dir ) == dirname( __FILE__ ) ? "true" : "false"; ?>;
this.editor = null; // global ace editor
this.fileChanged = false; // flag for check if file was changed already
this.currentDir = ""; // this is the global variable for the current directory; it is used for AJAX requests
@@ -62,16 +63,20 @@ function IFM() {
else if( self.config.edit == 1 && data[i].name.toLowerCase().substr(-4) != ".zip" )
newRow += ' data-eaction="edit"';
newRow += '><td><a tabindex="0"';
var guid = self.generateGuid();
if(data[i].type=="file") {
newRow += ' href="'+self.pathCombine(ifm.currentDir,data[i].name)+'"';
if( data[i].icon.indexOf( 'file-image' ) !== -1 )
newRow += ' data-toggle="tooltip" title="<img src=\''+self.pathCombine(self.currentDir,data[i].name)+'\' class=\'imgpreview\'>"';
if( self.isDocroot ) {
newRow += ' href="'+self.pathCombine(ifm.currentDir,data[i].name)+'"';
if( data[i].icon.indexOf( 'file-image' ) !== -1 )
newRow += ' data-toggle="tooltip" title="<img src=\''+self.pathCombine(self.currentDir,data[i].name)+'\' class=\'imgpreview\'"';
} else {
newRow += ' onclick="$(\'#d_'+guid+'\').submit();"';
}
} else {
newRow += ' onclick="ifm.changeDirectory(\''+data[i].name+'\')"';
}
newRow += '><span class="'+data[i].icon+'"></span> ' + ( data[i].name == '..' ? '[ up ]' : data[i].name ) + '</a></td>';
if( ( data[i].type != "dir" && self.config.download == 1 ) || ( data[i].type == "dir" && self.config.zipnload == 1 ) ) {
var guid = self.generateGuid();
newRow += '<td><form id="d_' + guid + '">';
newRow += '<input type="hidden" name="dir" value="' + self.currentDir + '">';
newRow += '<input type="hidden" name="filename" value="' + ( data[i].name == '..' ? '.' : data[i].name ) + '">';

View File

@@ -54,7 +54,7 @@ class IFM {
<div class="form-group">
<div class="input-group">
<span class="input-group-addon" id="currentDirLabel">Content of <span id="docroot">';
if( IFMConfig::showpath == 1 ) print $this->getScriptRoot().'/'; else print '/';
print ( IFMConfig::showpath == 1 ) ? realpath( IFMConfig::root_dir ) : "/";
print '</span></span><input class="form-control" id="currentDir" aria-describedby="currentDirLabel" type="text">
</div>
</div>
@@ -126,9 +126,9 @@ class IFM {
private function handleRequest() {
if($_REQUEST["api"] == "getRealpath") {
if( isset( $_REQUEST["dir"] ) && $_REQUEST["dir"] != "" )
$this->getRealpath( $_REQUEST["dir"] );
echo json_encode( array( "realpath" => $this->getValidDir( $_REQUEST["dir"] ) ) );
else
echo json_encode(array("realpath"=>""));
echo json_encode( array( "realpath" => "" ) );
}
elseif( $_REQUEST["api"] == "getFiles" ) {
if( isset( $_REQUEST["dir"] ) && $this->isPathValid( $_REQUEST["dir"] ) )
@@ -160,6 +160,11 @@ class IFM {
public function run() {
if ( $this->checkAuth() ) {
// go to our root_dir
if( ! is_dir( realpath( IFMConfig::root_dir ) ) || ! is_readable( realpath( IFMConfig::root_dir ) ) )
die( "Cannot access root_dir.");
else
chdir( IFMConfig::root_dir );
if ( ! isset($_REQUEST['api']) ) {
$this->getApplication();
} else {
@@ -670,14 +675,6 @@ class IFM {
</html>';
}
private function getValidDir($dir) {
if( $this->getScriptRoot() != substr( realpath( $dir ), 0, strlen( $this->getScriptRoot() ) ) ) {
return "";
} else {
return ( file_exists( realpath( $dir ) ) ) ? substr( realpath( $dir ), strlen( $this->getScriptRoot() ) + 1 ) : "";
}
}
private function filePermsDecode( $perms ) {
$oct = str_split( strrev( decoct( $perms ) ), 1 );
$masks = array( '---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx' );
@@ -690,17 +687,36 @@ class IFM {
);
}
private function isPathValid($p) {
if( $p == "" ) {
return true;
} elseif( str_replace( "\\", "/", $this->getScriptRoot() ) == str_replace( "\\", "/", substr( realpath( dirname( $p ) ), 0, strlen( $this->getScriptRoot() ) ) ) ) {
return true;
private function getValidDir( $dir ) {
if( ! $this->isPathValid( $dir ) || ! is_dir( $dir ) ) {
return "";
} else {
$rpDir = realpath( $dir );
$rpConfig = realpath( IFMConfig::root_dir );
if( $rpConfig == "/" )
return $rpDir;
elseif( $rpDir == $rpConfig )
return "";
else
return substr( $rpDir, strlen( $rpConfig ) + 1 );
}
return false;
}
private function isPathValid( $dir ) {
$rpDir = realpath( $dir );
$rpConfig = realpath( IFMConfig::root_dir );
if( ! is_string( $rpDir ) || ! is_string( $rpConfig ) ) // can happen if open_basedir is in effect
return false;
elseif( $rpDir == $rpConfig )
return true;
elseif( 0 === strpos( $rpDir, $rpConfig ) ) {
return true;
}
else
return false;
}
private function getScriptRoot() {
//return realpath( substr( $_SERVER["SCRIPT_FILENAME"], 0, strrpos( $_SERVER["SCRIPT_FILENAME"], "/" ) ) );
return dirname( $_SERVER["SCRIPT_FILENAME"] );
}
@@ -725,15 +741,6 @@ class IFM {
}
}
private function getRealpath($dir) {
if( $this->getScriptRoot() != substr( realpath( $_POST["dir"] ), 0, strlen( $this->getScriptRoot() ) ) ) {
echo json_encode( array( "realpath" => "" ) );
} else {
$rp = substr( realpath( $_POST["dir"] ), strlen( $this->getScriptRoot() ) + 1 );
if( $rp == false ) $rp = "";
echo json_encode( array( "realpath" => $rp ) );
}
}
private function rec_rmdir( $path ) {
if( !is_dir( $path ) ) {
return -1;