mirror of
https://github.com/michalcz10/USB-RAID-Array.git
synced 2026-11-11 07:59:04 +00:00
Use portable POSIX parent paths instead of platform-dependent dirname() for remote navigation, previews, uploads, file operations and shared URLs. Normalize browser paths, avoid doubled root separators and preserve top-level directory names in ZIP downloads. Add regression coverage for root navigation, generated links, relative paths and ZIP members, and document the new test command. Verified with PHP syntax checks and all three regression suites.
244 lines
7.5 KiB
PHP
244 lines
7.5 KiB
PHP
<?php
|
|
session_start();
|
|
|
|
if(!isset($_SESSION['uname'])){
|
|
header("location: ../../index.php");
|
|
session_destroy();
|
|
exit;
|
|
}
|
|
|
|
// Check if user has permission to upload/modify
|
|
if(!isset($_SESSION["upPer"]) || $_SESSION["upPer"] != true) {
|
|
die("You don't have permission to extract archives.");
|
|
}
|
|
|
|
// Include error reporting for debugging
|
|
ini_set('display_errors', 1);
|
|
error_reporting(E_ALL);
|
|
|
|
require_once __DIR__ . '/../../config/config.php';
|
|
use phpseclib3\Net\SFTP;
|
|
|
|
$sftp = initializeSFTP();
|
|
|
|
// Process extraction request
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['archive'])) {
|
|
$archivePath = $_POST['archive'];
|
|
$dirPath = remoteDirname($archivePath);
|
|
$archiveName = basename($archivePath);
|
|
$extension = pathinfo($archiveName, PATHINFO_EXTENSION);
|
|
|
|
// Create a temporary local directory for extraction
|
|
$tempDir = sys_get_temp_dir() . '/sftp_extract_' . time();
|
|
if (!mkdir($tempDir, 0777, true)) {
|
|
die("Failed to create temporary directory");
|
|
}
|
|
|
|
// Download the archive to the temp directory
|
|
$localArchivePath = $tempDir . '/' . $archiveName;
|
|
if (!$sftp->get($archivePath, $localArchivePath)) {
|
|
rmdir($tempDir);
|
|
die("Failed to download the archive");
|
|
}
|
|
|
|
// Detect archive type and extract
|
|
$extractionSuccess = false;
|
|
|
|
try {
|
|
// Determine the extraction method based on file extension
|
|
switch (strtolower($extension)) {
|
|
case 'zip':
|
|
$extractionSuccess = extractZip($localArchivePath, $tempDir);
|
|
break;
|
|
|
|
case 'rar':
|
|
$extractionSuccess = extractRar($localArchivePath, $tempDir);
|
|
break;
|
|
|
|
case 'tar':
|
|
case 'gz':
|
|
case 'bz2':
|
|
case 'xz':
|
|
case '7z':
|
|
$extractionSuccess = extractArchive($localArchivePath, $tempDir);
|
|
break;
|
|
|
|
default:
|
|
die("Unsupported archive format");
|
|
}
|
|
|
|
if ($extractionSuccess) {
|
|
// Upload extracted files back to the server
|
|
uploadExtractedFiles($sftp, $tempDir, $dirPath);
|
|
|
|
// Clean up temporary directory
|
|
deleteDirectory($tempDir);
|
|
|
|
// Redirect back to the file listing
|
|
header("Location: index.php?path=" . urlencode($dirPath));
|
|
exit;
|
|
} else {
|
|
die("Failed to extract the archive");
|
|
}
|
|
} catch (Exception $e) {
|
|
deleteDirectory($tempDir);
|
|
die("Error during extraction: " . $e->getMessage());
|
|
}
|
|
} else {
|
|
header("Location: index.php");
|
|
exit;
|
|
}
|
|
|
|
// Extract ZIP archives
|
|
function extractZip($archivePath, $destination) {
|
|
$zip = new ZipArchive();
|
|
|
|
if ($zip->open($archivePath) === TRUE) {
|
|
$zip->extractTo($destination);
|
|
$zip->close();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Extract RAR archives (requires rar extension or unrar command)
|
|
function extractRar($archivePath, $destination) {
|
|
// Try PHP Rar extension first
|
|
if (extension_loaded('rar')) {
|
|
$rar = RarArchive::open($archivePath);
|
|
if ($rar) {
|
|
$entries = $rar->getEntries();
|
|
foreach ($entries as $entry) {
|
|
$entry->extract($destination);
|
|
}
|
|
$rar->close();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Fallback to command line unrar if available
|
|
if (shell_exec("which unrar") || file_exists('C:\\Program Files\\WinRAR\\UnRAR.exe')) {
|
|
$command = '';
|
|
|
|
if (PHP_OS_FAMILY === 'Windows') {
|
|
$command = '"C:\\Program Files\\WinRAR\\UnRAR.exe" x -o+ ' . escapeshellarg($archivePath) . ' ' . escapeshellarg($destination);
|
|
} else {
|
|
$command = 'unrar x -o+ ' . escapeshellarg($archivePath) . ' ' . escapeshellarg($destination);
|
|
}
|
|
|
|
exec($command, $output, $returnCode);
|
|
return $returnCode === 0;
|
|
}
|
|
|
|
throw new Exception("RAR extraction is not available. Please install PHP RAR extension or UnRAR command line tool.");
|
|
}
|
|
|
|
// Extract other archives using system commands
|
|
function extractArchive($archivePath, $destination) {
|
|
$extension = pathinfo($archivePath, PATHINFO_EXTENSION);
|
|
$command = '';
|
|
|
|
// Change to the destination directory
|
|
$currentDir = getcwd();
|
|
chdir($destination);
|
|
|
|
if (PHP_OS_FAMILY === 'Windows') {
|
|
// For Windows, you'll need to have 7-Zip installed
|
|
$sevenZipPath = 'C:\\Program Files\\7-Zip\\7z.exe';
|
|
if (file_exists($sevenZipPath)) {
|
|
$command = '"' . $sevenZipPath . '" x ' . escapeshellarg($archivePath);
|
|
} else {
|
|
throw new Exception("7-Zip is not installed or not found at the expected location.");
|
|
}
|
|
} else {
|
|
// For Linux/Unix systems
|
|
switch (strtolower($extension)) {
|
|
case 'tar':
|
|
$command = 'tar -xf ' . escapeshellarg($archivePath);
|
|
break;
|
|
case 'gz':
|
|
if (strpos($archivePath, '.tar.gz') !== false) {
|
|
$command = 'tar -xzf ' . escapeshellarg($archivePath);
|
|
} else {
|
|
$command = 'gzip -d ' . escapeshellarg($archivePath);
|
|
}
|
|
break;
|
|
case 'bz2':
|
|
if (strpos($archivePath, '.tar.bz2') !== false) {
|
|
$command = 'tar -xjf ' . escapeshellarg($archivePath);
|
|
} else {
|
|
$command = 'bzip2 -d ' . escapeshellarg($archivePath);
|
|
}
|
|
break;
|
|
case 'xz':
|
|
if (strpos($archivePath, '.tar.xz') !== false) {
|
|
$command = 'tar -xJf ' . escapeshellarg($archivePath);
|
|
} else {
|
|
$command = 'xz -d ' . escapeshellarg($archivePath);
|
|
}
|
|
break;
|
|
case '7z':
|
|
$command = '7z x ' . escapeshellarg($archivePath);
|
|
break;
|
|
default:
|
|
throw new Exception("Unsupported archive format");
|
|
}
|
|
}
|
|
|
|
exec($command, $output, $returnCode);
|
|
|
|
// Change back to the original directory
|
|
chdir($currentDir);
|
|
|
|
return $returnCode === 0;
|
|
}
|
|
|
|
// Upload extracted files back to the SFTP server
|
|
function uploadExtractedFiles($sftp, $localDir, $remoteDir) {
|
|
$items = scandir($localDir);
|
|
|
|
foreach ($items as $item) {
|
|
if ($item === '.' || $item === '..') continue;
|
|
|
|
$localPath = $localDir . '/' . $item;
|
|
$remotePath = $remoteDir . '/' . $item;
|
|
|
|
if (is_dir($localPath)) {
|
|
// Create the directory on the remote server
|
|
if (!$sftp->is_dir($remotePath)) {
|
|
$sftp->mkdir($remotePath);
|
|
}
|
|
|
|
// Upload the contents of the directory
|
|
uploadExtractedFiles($sftp, $localPath, $remotePath);
|
|
} else {
|
|
// Upload the file - use the proper phpseclib3 method
|
|
$sftp->put($remotePath, $localPath, SFTP::SOURCE_LOCAL_FILE);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Recursively delete a directory
|
|
function deleteDirectory($dir) {
|
|
if (!is_dir($dir)) {
|
|
return;
|
|
}
|
|
|
|
$items = scandir($dir);
|
|
|
|
foreach ($items as $item) {
|
|
if ($item === '.' || $item === '..') continue;
|
|
|
|
$path = $dir . '/' . $item;
|
|
|
|
if (is_dir($path)) {
|
|
deleteDirectory($path);
|
|
} else {
|
|
unlink($path);
|
|
}
|
|
}
|
|
|
|
rmdir($dir);
|
|
}
|
|
?>
|