diff --git a/emhttp/plugins/dynamix/Browse.page b/emhttp/plugins/dynamix/Browse.page index 1d18c2a97..9f9ca88dd 100644 --- a/emhttp/plugins/dynamix/Browse.page +++ b/emhttp/plugins/dynamix/Browse.page @@ -488,7 +488,7 @@ function doAction(action, title, id) { case 4: // move folder case 9: // move file // disallow mixing of disk and user shares - var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|rootshare)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)).+$|^\/boot\/.+/); + var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|disks|remotes)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)\/).+$|^\/boot\/.+/); // check if 'mv' can be used if (path.length > 2) { if (user) { @@ -520,7 +520,7 @@ function doAction(action, title, id) { break; default: // disallow mixing of disk and user shares - var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|rootshare)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)).+$|^\/boot\/.+/); + var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|disks|remotes)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)\/).+$|^\/boot\/.+/); break; } if (!target || !valid.test(target)) {errorTarget(); return;} @@ -558,7 +558,7 @@ function doAction(action, title, id) { case 4: // move folder case 9: // move file // disallow mixing of disk and user shares - var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|rootshare)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)).+$|^\/boot\/.+/); + var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|disks|remotes)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)\/).+$|^\/boot\/.+/); // check if 'mv' can be used if (path.length > 2) { if (user) { @@ -583,7 +583,7 @@ function doAction(action, title, id) { break; default: // disallow mixing of disk and user shares - var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|rootshare)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)).+$|^\/boot\/.+/); + var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|disks|remotes)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)\/).+$|^\/boot\/.+/); break; } if (!target || !valid.test(target)) {errorTarget(); return;} @@ -767,7 +767,7 @@ function doActions(action, title) { break; case 4: // move object // disallow mixing of disk and user shares - var valid = ud ? /\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|rootshare)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)).+$|^\/boot\/.+/); + var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|disks|remotes)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)\/).+$|^\/boot\/.+/); // check if 'mv' can be used if (path.length > 2) { if (user) { @@ -801,7 +801,7 @@ function doActions(action, title) { break; default: // disallow mixing of disk and user shares - var valid = ud ? /\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|rootshare)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)).+$|^\/boot\/.+/); + var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|disks|remotes)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)\/).+$|^\/boot\/.+/); break; } if (!target || !valid.test(target)) {errorTarget(); return;} @@ -839,7 +839,7 @@ function doActions(action, title) { break; case 4: // move object // disallow mixing of disk and user shares - var valid = ud ? /\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|rootshare)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)).+$|^\/boot\/.+/); + var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|disks|remotes)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)\/).+$|^\/boot\/.+/); // check if 'mv' can be used if (path.length > 2) { if (user) { @@ -866,7 +866,7 @@ function doActions(action, title) { break; default: // disallow mixing of disk and user shares - var valid = ud ? /\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|rootshare)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)).+$|^\/boot\/.+/); + var valid = ud ? /^\/mnt\/.+/ : (user ? /^\/mnt\/(user0?|disks|remotes)\/.+/ : /^\/mnt\/(?!.*(user0?|rootshare)\/).+$|^\/boot\/.+/); break; } if (!target || !valid.test(target)) {errorTarget(); return;} diff --git a/emhttp/plugins/dynamix/include/Browse.php b/emhttp/plugins/dynamix/include/Browse.php index 1e58d5811..4486f04bf 100644 --- a/emhttp/plugins/dynamix/include/Browse.php +++ b/emhttp/plugins/dynamix/include/Browse.php @@ -25,18 +25,18 @@ function write(&$rows) { function validdir($dir) { $path = realpath($dir); - return in_array(explode('/',$path)[1]??'',['mnt','boot']) ? $path : ''; + return in_array(explode('/', $path)[1] ?? '', ['mnt','boot']) ? $path : ''; } function escapeQuote($data) { - return str_replace('"','"',$data); + return str_replace('"','"', $data); } function add($number, $name, $single='', $plural='s') { return $number.' '._($name.($number==1 ? $single : $plural)); } -function age($number,$time) { +function age($number, $time) { return sprintf(_('%s '.($number==1 ? $time : $time.'s').' ago'),$number); } @@ -44,25 +44,25 @@ function my_age($time) { if (!is_numeric($time)) $time = time(); $age = new DateTime('@'.$time); $age = date_create('now')->diff($age); - if ($age->y > 0) return age($age->y,'year'); - if ($age->m > 0) return age($age->m,'month'); - if ($age->d > 0) return age($age->d,'day'); - if ($age->h > 0) return age($age->h,'hour'); - if ($age->i > 0) return age($age->i,'minute'); - return age($age->s,'second'); + if ($age->y > 0) return age($age->y, 'year'); + if ($age->m > 0) return age($age->m, 'month'); + if ($age->d > 0) return age($age->d, 'day'); + if ($age->h > 0) return age($age->h, 'hour'); + if ($age->i > 0) return age($age->i, 'minute'); + return age($age->s, 'second'); } function parent_link() { - global $dir,$path; + global $dir, $path; $parent = dirname($dir); - return $parent=='/' ? false : ''._('Parent Directory').''; + return $parent == '/' ? false : ''._('Parent Directory').''; } function my_devs(&$devs,$name,$menu) { - global $disks,$lock; + global $disks, $lock; $text = []; $i = 0; foreach ($devs as $dev) { - if ($lock=='---') { + if ($lock == '---') { $text[$i] = ' ---'; } else { switch ($disks[$dev]['luksState']??0) { @@ -72,7 +72,7 @@ function my_devs(&$devs,$name,$menu) { case 3: $text[$i] = ''._('Locked: wrong encryption key').''; break; default: $text[$i] = ''._('Locked: unknown error').''; break; } - $root = $dev=='flash' ? "/boot/$name" : "/mnt/$dev/$name"; + $root = ($dev == 'flash' ? "/boot/$name" : "/mnt/$dev/$name"); $text[$i] .= ''.compress($dev,11,0).''; } $i++; @@ -141,8 +141,8 @@ $path = unscript($_GET['path']); $fmt = "%F {$display['time']}"; $dirs = $files = []; $total = $objs = 0; -[$null,$root,$main,$next,$rest] = my_explode('/',$dir,5); -$user = $root=='mnt' && in_array($main,['user','user0']); +[$null,$root,$main,$next,$rest] = my_explode('/', $dir, 5); +$user = $root=='mnt' && in_array($main, ['user','user0']); $lock = $root=='mnt' ? ($main ?: '---') : ($root=='boot' ? _('flash') : '---'); $ishare = $root=='mnt' && (!$main || !$next || ($main=='rootshare' && !$rest)); $folder = $lock=='---' ? _('DEVICE') : ($ishare ? _('SHARE') : _('FOLDER')); @@ -154,13 +154,14 @@ if ($user ) { } $stat = popen("shopt -s dotglob;stat -L -c'%F|%U|%A|%s|%Y|%n' ".escapeshellarg($dir)."/* 2>/dev/null",'r'); -while (($row = fgets($stat))!==false) { + +while (($row = fgets($stat)) !== false) { [$type,$owner,$perm,$size,$time,$name] = explode('|',rtrim($row,"\n"),6); - $dev = explode('/',$name,5); - $devs = explode(',',$user ? $set[basename($name)]??$shares[$dev[3]]['cachePool']??'' : $lock); + $dev = explode('/', $name, 5); + $devs = explode(',', $user ? $set[basename($name)] ?? $shares[$dev[3]]['cachePool'] ?? '' : $lock); $objs++; $text = []; - if ($type[0]=='d') { + if ($type[0] == 'd') { $text[] = ''; $text[] = ''; $text[] = ''.htmlspecialchars(basename($name)).''; @@ -172,8 +173,8 @@ while (($row = fgets($stat))!==false) { $text[] = '...'; $dirs[] = gzdeflate(implode($text)); } else { - $ext = strtolower(pathinfo($name,PATHINFO_EXTENSION)); - $tag = count($devs)>1 ? 'warning' : ''; + $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); + $tag = count($devs) > 1 ? 'warning' : ''; $text[] = ''; $text[] = ''; $text[] = ''.htmlspecialchars(basename($name)).''; @@ -189,6 +190,7 @@ while (($row = fgets($stat))!==false) { } pclose($stat); + if ($link = parent_link()) echo '',$link,''; echo write($dirs),write($files),'',add($objs,'object'),': ',add($dirs,'director','y','ies'),', ',add($files,'file'),' (',my_scale($total,$unit),' ',$unit,' ',_('total'),')'; ?> diff --git a/emhttp/plugins/dynamix/include/FileTree.php b/emhttp/plugins/dynamix/include/FileTree.php index 377b6657f..010aa5712 100644 --- a/emhttp/plugins/dynamix/include/FileTree.php +++ b/emhttp/plugins/dynamix/include/FileTree.php @@ -9,6 +9,7 @@ * * History: * + * 1.2.2 - allow user shares to UD shares * 1.2.1 - exclude folders from the /mnt/ root folder * 1.2.0 - adapted by Bergware for use in Unraid - support UTF-8 encoding & hardening * 1.1.1 - SECURITY: forcing root to prevent users from determining system's file structure (per DaveBrad) @@ -29,13 +30,19 @@ function path($dir) { return mb_substr($dir,-1) == '/' ? $dir : $dir.'/'; } + function is_top($dir) { global $root; return mb_strlen($dir) > mb_strlen($root); } -function is_low($dir) { - global $root; - return mb_substr($dir,0,mb_strlen($root)) == $root; + +function no_dots($name) { + return !in_array($name, ['.','..']); +} + +function my_dir($name) { + global $rootdir, $userdir, $topdir, $UDincluded; + return ($rootdir === $userdir && in_array($name, $UDincluded)) ? $topdir : $rootdir; } $root = path(realpath($_POST['root'])); @@ -44,62 +51,60 @@ if (!$root) exit("ERROR: Root filesystem directory not set in jqueryFileTree.php $docroot = '/usr/local/emhttp'; require_once "$docroot/webGui/include/Secure.php"; -$rootdir = path(realpath($_POST['dir'])); -$topdir = '/mnt/'; +$mntdir = '/mnt/'; $userdir = '/mnt/user/'; +$rootdir = path(realpath($_POST['dir'])); +$topdir = str_replace($userdir, $mntdir, $rootdir); $filters = (array)$_POST['filter']; $match = $_POST['match']; $checkbox = $_POST['multiSelect'] == 'true' ? "" : ""; -/* Excluded folders to not show in the dropdown in the '/mnt/' directory only. */ -$excludedFolders = ['RecycleBin', 'addons', 'rootshare']; -$udShares = ['disks','remotes']; +// Excluded UD shares to hide under '/mnt' +$UDexcluded = ['RecycleBin', 'addons', 'rootshare']; +// Included UD shares to show under '/mnt/user' +$UDincluded = ['disks','remotes']; echo "