diff --git a/emhttp/plugins/dynamix/Browse.page b/emhttp/plugins/dynamix/Browse.page index 774dbc49c..06bd0bf89 100644 --- a/emhttp/plugins/dynamix/Browse.page +++ b/emhttp/plugins/dynamix/Browse.page @@ -1390,8 +1390,7 @@ function xlink(link) { }, function(isConfirm) { if (isConfirm === false) { // Terminal button was clicked (cancel button) - var d = new Date(); - openTerminal('ttyd', 'File_Manager_' + d.getTime(), path); + openTerminal('ttyd', 'file.manager.terminal', path); } // Ok button (isConfirm === true) or dialog dismissed - just close }); diff --git a/emhttp/plugins/dynamix/include/OpenTerminal.php b/emhttp/plugins/dynamix/include/OpenTerminal.php index a24115106..032165520 100644 --- a/emhttp/plugins/dynamix/include/OpenTerminal.php +++ b/emhttp/plugins/dynamix/include/OpenTerminal.php @@ -40,6 +40,10 @@ function command($path,$file) { global $run,$wait,$rows; return (file_exists($file) && substr($file,0,strlen($path))==$path) ? "$run tail -f -n $rows '$file'" : $wait; } +function sed_escape($s) { + // escape sed replacement meta characters: & and \ + return str_replace(['\\', '&'], ['\\\\', '\\&'], $s); +} switch ($_GET['tag']) { case 'ttyd': // check if ttyd already running @@ -65,29 +69,36 @@ function command($path,$file) { $real_path = '/root'; } - $name = unbundle($_GET['name']); - $exec = "/var/tmp/$name.run.sh"; + // Set script variables + $unique_id = getmypid() . '_' . uniqid(); // prevent race condition with multiple terminals + $exec = "/var/tmp/file.manager.terminal.$unique_id.sh"; + $profile = "/tmp/file.manager.terminal.$unique_id.profile"; $escaped_path = str_replace("'", "'\\''", $real_path); - // Escape sed metacharacters: & (matched string), \\ (escape char), / (delimiter) - $sed_escaped = str_replace(['\\', '&', '/'], ['\\\\', '\\&', '\\/'], $escaped_path); + $sed_escaped = sed_escape($escaped_path); + + // Get user's shell (same as standard terminal) + $user_shell = posix_getpwuid(0)['shell']; // Create startup script similar to ~/.bashrc // Note: We can not use ~/.bashrc as it loads /etc/profile which does 'cd $HOME' + // Note: Script deletes itself before exec (bash has already loaded the script into memory) $script_content = << /tmp/$name.profile -source /tmp/$name.profile +sed 's#^cd \$HOME#cd '\''$sed_escaped'\''#' /etc/profile > '$profile' +source '$profile' source /root/.bash_profile 2>/dev/null -rm /tmp/$name.profile -exec bash --norc -i +rm '$profile' +# Delete this script and exec shell (bash has already loaded this into memory) +{ rm -f '$exec'; exec $user_shell --norc -i; } BASH; file_put_contents($exec, $script_content); chmod($exec, 0755); exec("ttyd-exec -i '$sock' $exec"); + + // Standard login shell } else { - // Standard login shell if ($retval != 0) exec("ttyd-exec -i '$sock' '" . posix_getpwuid(0)['shell'] . "' --login"); } break;