From 8b02b57a410a5165fc4418e381ecb6f81615bb77 Mon Sep 17 00:00:00 2001 From: Marco Dickert Date: Wed, 26 Jul 2017 02:32:32 +0200 Subject: [PATCH] added support for archive file types: tar, tar.gz, tar.bz2, tgz closes #44 --- build/libifm.php | 74 +++++++++++++++++++++--------- compiler.php | 2 +- ifm.php | 74 +++++++++++++++++++++--------- src/ifm.js | 19 ++++---- src/{ifmzip.php => ifmarchive.php} | 24 ++++++++-- src/main.php | 31 +++++++++---- 6 files changed, 157 insertions(+), 67 deletions(-) rename src/{ifmzip.php => ifmarchive.php} (74%) diff --git a/build/libifm.php b/build/libifm.php index c760448..b173c65 100644 --- a/build/libifm.php +++ b/build/libifm.php @@ -840,22 +840,21 @@ function IFM( params ) { item.download.icon = "icon icon-download"; if( item.icon.indexOf( 'file-image' ) !== -1 && self.config.isDocroot ) item.tooltip = 'data-toggle="tooltip" title=""'; - if( item.ext == "zip" ) + if( self.inArray( item.ext, ["zip","tar","tgz","tar.gz","tar.xz","tar.bz2"] ) ) { item.eaction = "extract"; - else - item.eaction = "edit"; - if( self.config.edit && item.ext != "zip" && item.icon.indexOf( 'file-image' ) == -1) - item.button.push({ - action: "edit", - icon: "icon icon-pencil", - title: "edit" - }); - if( self.config.extract && item.ext == "zip" ) item.button.push({ action: "extract", icon: "icon icon-archive", title: "extract" }); + } else if( self.config.edit && item.icon.indexOf( 'file-image' ) == -1) { + item.eaction = "edit"; + item.button.push({ + action: "edit", + icon: "icon icon-pencil", + title: "edit" + }); + } } if( ! self.inArray( item.name, [".", ".."] ) ) { if( self.config.copymove ) @@ -2181,7 +2180,12 @@ function IFM( params ) { $item["icon"] = "icon icon-folder-empty"; } else { $item["type"] = "file"; - $type = substr( strrchr( $result, "." ), 1 ); + if( in_array( substr( $result, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) + $type = substr( $result, -6 ); + elseif( substr( $result, -8 ) == ".tar.bz2" ) + $type = "tar.bz2"; + else + $type = substr( strrchr( $result, "." ), 1 ); $item["icon"] = $this->getTypeIcon( $type ); $item["ext"] = strtolower($type); } @@ -2453,8 +2457,8 @@ function IFM( params ) { echo json_encode( array( "status" => "ERROR", "message" => "No permission to extract files" ) ); else { $this->chDirIfNecessary( $d['dir'] ); - if( ! file_exists( $d['filename'] ) || substr( $d['filename'],-4 ) != ".zip" ) { - echo json_encode( array( "status" => "ERROR","message" => "No valid zip file found" ) ); + if( ! file_exists( $d['filename'] ) ) { + echo json_encode( array( "status" => "ERROR","message" => "No valid archive found" ) ); exit( 1 ); } if( ! isset( $d['targetdir'] ) || trim( $d['targetdir'] ) == "" ) @@ -2467,11 +2471,19 @@ function IFM( params ) { echo json_encode( array( "status" => "ERROR","message" => "Could not create target directory." ) ); exit( 1 ); } - if( ! IFMZip::extract( $d['filename'], $d['targetdir'] ) ) { - echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); + if( substr( strtolower( $d['filename'] ), -4 ) == ".zip" ) { + if( ! IFMArchive::extractZip( $d['filename'], $d['targetdir'] ) ) { + echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); + } else { + echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); + } } else { - echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); - } + if( ! IFMArchive::extractTar( $d['filename'], $d['targetdir'] ) ) { + echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); + } else { + echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); + } + } } } @@ -2559,7 +2571,7 @@ function IFM( params ) { unset( $zip ); $dfile = $this->pathCombine( $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename try { - IFMZip::create( realpath( $d['filename'] ), $dfile, ( $d['filename'] == "." ) ); + IFMArchive::createZip( realpath( $d['filename'] ), $dfile, ( $d['filename'] == "." ) ); if( $d['filename'] == "." ) { if( getcwd() == $this->getScriptRoot() ) $d['filename'] = "root"; @@ -2803,7 +2815,7 @@ function IFM( params ) { case "csv": case "ods": case "xls": case "xlsx": return 'icon icon-file-excel'; break; case "odp": case "ppt": case "pptx": return 'icon icon-file-powerpoint'; break; case "pdf": return 'icon icon-file-pdf'; break; - case "tgz": case "zip": case "tar": case "7z": case "rar": return 'icon icon-file-archive'; + case "tgz": case "zip": case "tar": case "tgz": case "tar.gz": case "tar.xz": case "tar.bz2": case "7z": case "rar": return 'icon icon-file-archive'; default: return 'icon icon-doc'; } } @@ -2950,7 +2962,7 @@ function IFM( params ) { * this was adapted from http://php.net/manual/de/class.ziparchive.php#110719 */ -class IFMZip { +class IFMArchive { /** * Add a folder to the zip file */ @@ -2978,7 +2990,7 @@ class IFMZip { /** * Create a zip file */ - public static function create( $src, $out, $root=false ) + public static function createZip( $src, $out, $root=false ) { $z = new ZipArchive(); $z->open( $out, ZIPARCHIVE::CREATE); @@ -3000,7 +3012,7 @@ class IFMZip { /** * Unzip a zip file */ - public static function extract( $file, $destination="./" ) { + public static function extractZip( $file, $destination="./" ) { $zip = new ZipArchive; $res = $zip->open( $file ); if( $res === true ) { @@ -3011,6 +3023,24 @@ class IFMZip { return false; } } + + public static function extractTar( $file, $destination="./" ) { + if( ! file_exists( $file ) ) + return false; + $tar = new PharData( $file ); + file_put_contents( "debug.txt", "Exist: asparagus?" . ( file_exists( "asparagus") ? "yes" : "no" ) ); + try { + $tar->extractTo( $destination, null, true ); + return true; + } catch (Exception $e) { + return false; + } + } + + public static function createTar( $src, $out, $root=false ) { + $tar = new PharData( $out ); + $tar->buildFromDirectory( $src ); + } } /** * htpasswd parser diff --git a/compiler.php b/compiler.php index cc13c0d..6eae1ca 100755 --- a/compiler.php +++ b/compiler.php @@ -9,7 +9,7 @@ chdir( realpath( dirname( __FILE__ ) ) ); $IFM_SRC_MAIN = "src/main.php"; -$IFM_SRC_PHPFILES = array( "src/ifmzip.php", "src/htpasswd.php" ); +$IFM_SRC_PHPFILES = array( "src/ifmarchive.php", "src/htpasswd.php" ); $IFM_SRC_JS = "src/ifm.js"; $IFM_BUILD_STANDALONE = "ifm.php"; diff --git a/ifm.php b/ifm.php index 3d54edc..e5ab9c3 100644 --- a/ifm.php +++ b/ifm.php @@ -840,22 +840,21 @@ function IFM( params ) { item.download.icon = "icon icon-download"; if( item.icon.indexOf( 'file-image' ) !== -1 && self.config.isDocroot ) item.tooltip = 'data-toggle="tooltip" title=""'; - if( item.ext == "zip" ) + if( self.inArray( item.ext, ["zip","tar","tgz","tar.gz","tar.xz","tar.bz2"] ) ) { item.eaction = "extract"; - else - item.eaction = "edit"; - if( self.config.edit && item.ext != "zip" && item.icon.indexOf( 'file-image' ) == -1) - item.button.push({ - action: "edit", - icon: "icon icon-pencil", - title: "edit" - }); - if( self.config.extract && item.ext == "zip" ) item.button.push({ action: "extract", icon: "icon icon-archive", title: "extract" }); + } else if( self.config.edit && item.icon.indexOf( 'file-image' ) == -1) { + item.eaction = "edit"; + item.button.push({ + action: "edit", + icon: "icon icon-pencil", + title: "edit" + }); + } } if( ! self.inArray( item.name, [".", ".."] ) ) { if( self.config.copymove ) @@ -2181,7 +2180,12 @@ function IFM( params ) { $item["icon"] = "icon icon-folder-empty"; } else { $item["type"] = "file"; - $type = substr( strrchr( $result, "." ), 1 ); + if( in_array( substr( $result, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) + $type = substr( $result, -6 ); + elseif( substr( $result, -8 ) == ".tar.bz2" ) + $type = "tar.bz2"; + else + $type = substr( strrchr( $result, "." ), 1 ); $item["icon"] = $this->getTypeIcon( $type ); $item["ext"] = strtolower($type); } @@ -2453,8 +2457,8 @@ function IFM( params ) { echo json_encode( array( "status" => "ERROR", "message" => "No permission to extract files" ) ); else { $this->chDirIfNecessary( $d['dir'] ); - if( ! file_exists( $d['filename'] ) || substr( $d['filename'],-4 ) != ".zip" ) { - echo json_encode( array( "status" => "ERROR","message" => "No valid zip file found" ) ); + if( ! file_exists( $d['filename'] ) ) { + echo json_encode( array( "status" => "ERROR","message" => "No valid archive found" ) ); exit( 1 ); } if( ! isset( $d['targetdir'] ) || trim( $d['targetdir'] ) == "" ) @@ -2467,11 +2471,19 @@ function IFM( params ) { echo json_encode( array( "status" => "ERROR","message" => "Could not create target directory." ) ); exit( 1 ); } - if( ! IFMZip::extract( $d['filename'], $d['targetdir'] ) ) { - echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); + if( substr( strtolower( $d['filename'] ), -4 ) == ".zip" ) { + if( ! IFMArchive::extractZip( $d['filename'], $d['targetdir'] ) ) { + echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); + } else { + echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); + } } else { - echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); - } + if( ! IFMArchive::extractTar( $d['filename'], $d['targetdir'] ) ) { + echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); + } else { + echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); + } + } } } @@ -2559,7 +2571,7 @@ function IFM( params ) { unset( $zip ); $dfile = $this->pathCombine( $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename try { - IFMZip::create( realpath( $d['filename'] ), $dfile, ( $d['filename'] == "." ) ); + IFMArchive::createZip( realpath( $d['filename'] ), $dfile, ( $d['filename'] == "." ) ); if( $d['filename'] == "." ) { if( getcwd() == $this->getScriptRoot() ) $d['filename'] = "root"; @@ -2803,7 +2815,7 @@ function IFM( params ) { case "csv": case "ods": case "xls": case "xlsx": return 'icon icon-file-excel'; break; case "odp": case "ppt": case "pptx": return 'icon icon-file-powerpoint'; break; case "pdf": return 'icon icon-file-pdf'; break; - case "tgz": case "zip": case "tar": case "7z": case "rar": return 'icon icon-file-archive'; + case "tgz": case "zip": case "tar": case "tgz": case "tar.gz": case "tar.xz": case "tar.bz2": case "7z": case "rar": return 'icon icon-file-archive'; default: return 'icon icon-doc'; } } @@ -2950,7 +2962,7 @@ function IFM( params ) { * this was adapted from http://php.net/manual/de/class.ziparchive.php#110719 */ -class IFMZip { +class IFMArchive { /** * Add a folder to the zip file */ @@ -2978,7 +2990,7 @@ class IFMZip { /** * Create a zip file */ - public static function create( $src, $out, $root=false ) + public static function createZip( $src, $out, $root=false ) { $z = new ZipArchive(); $z->open( $out, ZIPARCHIVE::CREATE); @@ -3000,7 +3012,7 @@ class IFMZip { /** * Unzip a zip file */ - public static function extract( $file, $destination="./" ) { + public static function extractZip( $file, $destination="./" ) { $zip = new ZipArchive; $res = $zip->open( $file ); if( $res === true ) { @@ -3011,6 +3023,24 @@ class IFMZip { return false; } } + + public static function extractTar( $file, $destination="./" ) { + if( ! file_exists( $file ) ) + return false; + $tar = new PharData( $file ); + file_put_contents( "debug.txt", "Exist: asparagus?" . ( file_exists( "asparagus") ? "yes" : "no" ) ); + try { + $tar->extractTo( $destination, null, true ); + return true; + } catch (Exception $e) { + return false; + } + } + + public static function createTar( $src, $out, $root=false ) { + $tar = new PharData( $out ); + $tar->buildFromDirectory( $src ); + } } /** * htpasswd parser diff --git a/src/ifm.js b/src/ifm.js index 53430b4..3f747fb 100644 --- a/src/ifm.js +++ b/src/ifm.js @@ -102,22 +102,21 @@ function IFM( params ) { item.download.icon = "icon icon-download"; if( item.icon.indexOf( 'file-image' ) !== -1 && self.config.isDocroot ) item.tooltip = 'data-toggle="tooltip" title=""'; - if( item.ext == "zip" ) + if( self.inArray( item.ext, ["zip","tar","tgz","tar.gz","tar.xz","tar.bz2"] ) ) { item.eaction = "extract"; - else - item.eaction = "edit"; - if( self.config.edit && item.ext != "zip" && item.icon.indexOf( 'file-image' ) == -1) - item.button.push({ - action: "edit", - icon: "icon icon-pencil", - title: "edit" - }); - if( self.config.extract && item.ext == "zip" ) item.button.push({ action: "extract", icon: "icon icon-archive", title: "extract" }); + } else if( self.config.edit && item.icon.indexOf( 'file-image' ) == -1) { + item.eaction = "edit"; + item.button.push({ + action: "edit", + icon: "icon icon-pencil", + title: "edit" + }); + } } if( ! self.inArray( item.name, [".", ".."] ) ) { if( self.config.copymove ) diff --git a/src/ifmzip.php b/src/ifmarchive.php similarity index 74% rename from src/ifmzip.php rename to src/ifmarchive.php index 304dcec..797d528 100644 --- a/src/ifmzip.php +++ b/src/ifmarchive.php @@ -12,7 +12,7 @@ * this was adapted from http://php.net/manual/de/class.ziparchive.php#110719 */ -class IFMZip { +class IFMArchive { /** * Add a folder to the zip file */ @@ -40,7 +40,7 @@ class IFMZip { /** * Create a zip file */ - public static function create( $src, $out, $root=false ) + public static function createZip( $src, $out, $root=false ) { $z = new ZipArchive(); $z->open( $out, ZIPARCHIVE::CREATE); @@ -62,7 +62,7 @@ class IFMZip { /** * Unzip a zip file */ - public static function extract( $file, $destination="./" ) { + public static function extractZip( $file, $destination="./" ) { $zip = new ZipArchive; $res = $zip->open( $file ); if( $res === true ) { @@ -73,4 +73,22 @@ class IFMZip { return false; } } + + public static function extractTar( $file, $destination="./" ) { + if( ! file_exists( $file ) ) + return false; + $tar = new PharData( $file ); + file_put_contents( "debug.txt", "Exist: asparagus?" . ( file_exists( "asparagus") ? "yes" : "no" ) ); + try { + $tar->extractTo( $destination, null, true ); + return true; + } catch (Exception $e) { + return false; + } + } + + public static function createTar( $src, $out, $root=false ) { + $tar = new PharData( $out ); + $tar->buildFromDirectory( $src ); + } } diff --git a/src/main.php b/src/main.php index 933f8cd..25ffef2 100644 --- a/src/main.php +++ b/src/main.php @@ -264,7 +264,12 @@ f00bar; $item["icon"] = "icon icon-folder-empty"; } else { $item["type"] = "file"; - $type = substr( strrchr( $result, "." ), 1 ); + if( in_array( substr( $result, -7 ), array( ".tar.gz", ".tar.xz" ) ) ) + $type = substr( $result, -6 ); + elseif( substr( $result, -8 ) == ".tar.bz2" ) + $type = "tar.bz2"; + else + $type = substr( strrchr( $result, "." ), 1 ); $item["icon"] = $this->getTypeIcon( $type ); $item["ext"] = strtolower($type); } @@ -536,8 +541,8 @@ f00bar; echo json_encode( array( "status" => "ERROR", "message" => "No permission to extract files" ) ); else { $this->chDirIfNecessary( $d['dir'] ); - if( ! file_exists( $d['filename'] ) || substr( $d['filename'],-4 ) != ".zip" ) { - echo json_encode( array( "status" => "ERROR","message" => "No valid zip file found" ) ); + if( ! file_exists( $d['filename'] ) ) { + echo json_encode( array( "status" => "ERROR","message" => "No valid archive found" ) ); exit( 1 ); } if( ! isset( $d['targetdir'] ) || trim( $d['targetdir'] ) == "" ) @@ -550,11 +555,19 @@ f00bar; echo json_encode( array( "status" => "ERROR","message" => "Could not create target directory." ) ); exit( 1 ); } - if( ! IFMZip::extract( $d['filename'], $d['targetdir'] ) ) { - echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); + if( substr( strtolower( $d['filename'] ), -4 ) == ".zip" ) { + if( ! IFMArchive::extractZip( $d['filename'], $d['targetdir'] ) ) { + echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); + } else { + echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); + } } else { - echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); - } + if( ! IFMArchive::extractTar( $d['filename'], $d['targetdir'] ) ) { + echo json_encode( array( "status" => "ERROR","message" => "File could not be extracted" ) ); + } else { + echo json_encode( array( "status" => "OK","message" => "File successfully extracted." ) ); + } + } } } @@ -642,7 +655,7 @@ f00bar; unset( $zip ); $dfile = $this->pathCombine( $this->config['tmp_dir'], uniqid( "ifm-tmp-" ) . ".zip" ); // temporary filename try { - IFMZip::create( realpath( $d['filename'] ), $dfile, ( $d['filename'] == "." ) ); + IFMArchive::createZip( realpath( $d['filename'] ), $dfile, ( $d['filename'] == "." ) ); if( $d['filename'] == "." ) { if( getcwd() == $this->getScriptRoot() ) $d['filename'] = "root"; @@ -886,7 +899,7 @@ f00bar; case "csv": case "ods": case "xls": case "xlsx": return 'icon icon-file-excel'; break; case "odp": case "ppt": case "pptx": return 'icon icon-file-powerpoint'; break; case "pdf": return 'icon icon-file-pdf'; break; - case "tgz": case "zip": case "tar": case "7z": case "rar": return 'icon icon-file-archive'; + case "tgz": case "zip": case "tar": case "tgz": case "tar.gz": case "tar.xz": case "tar.bz2": case "7z": case "rar": return 'icon icon-file-archive'; default: return 'icon icon-doc'; } }