mirror of
https://github.com/webmin/webmin.git
synced 2026-03-20 08:40:24 +00:00
Add support for loading shell initialization file directly
This commit is contained in:
@@ -295,7 +295,7 @@ if (!$@) {
|
||||
open(STDERR, ">&".fileno($ttyfh));
|
||||
close($ttyfh); # Already dup'd
|
||||
if ($binary) {
|
||||
exec $cmd $binary;
|
||||
exec "$cmd $binary";
|
||||
}
|
||||
else {
|
||||
exec($cmd);
|
||||
@@ -350,7 +350,7 @@ else {
|
||||
open(STDERR, ">&STDOUT");
|
||||
close($ptyfh);
|
||||
if ($binary) {
|
||||
exec $cmd $binary;
|
||||
exec "$cmd $binary";
|
||||
}
|
||||
else {
|
||||
exec($cmd);
|
||||
|
||||
58
xterm/.bashrc
Normal file
58
xterm/.bashrc
Normal file
@@ -0,0 +1,58 @@
|
||||
# source global definitions
|
||||
if [ -f /etc/bashrc ]; then
|
||||
. /etc/bashrc
|
||||
elif [ -f /etc/bash.bashrc ]; then
|
||||
. /etc/bash.bashrc
|
||||
fi
|
||||
|
||||
# user specific environment
|
||||
if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
|
||||
then
|
||||
PATH="$HOME/.local/bin:$HOME/bin:$PATH"
|
||||
fi
|
||||
export PATH
|
||||
|
||||
# don't put duplicate lines in the history. See bash(1) for more options
|
||||
# ... or force ignoredups and ignorespace
|
||||
HISTCONTROL=ignoredups:ignorespace
|
||||
|
||||
# append to the history file, don't overwrite it
|
||||
shopt -s histappend
|
||||
|
||||
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
|
||||
HISTSIZE=1000
|
||||
HISTFILESIZE=2000
|
||||
|
||||
# check the window size after each command and, if necessary,
|
||||
# update the values of LINES and COLUMNS.
|
||||
shopt -s checkwinsize
|
||||
|
||||
# enable color support of ls and also add handy aliases
|
||||
if [ -x /usr/bin/dircolors ]; then
|
||||
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
|
||||
alias ls='ls --color=auto'
|
||||
alias dir='dir --color=auto'
|
||||
alias vdir='vdir --color=auto'
|
||||
|
||||
alias grep='grep --color=auto'
|
||||
alias fgrep='fgrep --color=auto'
|
||||
alias egrep='egrep --color=auto'
|
||||
fi
|
||||
|
||||
# some more ls aliases
|
||||
alias ll='ls -alF'
|
||||
alias la='ls -A'
|
||||
alias l='ls -CF'
|
||||
|
||||
# custom PS1
|
||||
PS1='\[\033[1;35m\]\u\[\033[1;37m\]@\[\033[1;32m\]\h:\[\033[1;37m\]\w\[\033[1;37m\]\$\[\033[0m\] '
|
||||
|
||||
# user specific aliases and functions
|
||||
if [ -d ~/.bashrc.d ]; then
|
||||
for rc in ~/.bashrc.d/*; do
|
||||
if [ -f "$rc" ]; then
|
||||
. "$rc"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
unset rc
|
||||
@@ -1,2 +1,2 @@
|
||||
base_port=555
|
||||
flavors=1
|
||||
rcfile=1
|
||||
@@ -1,5 +1,3 @@
|
||||
base_port=Base port number for WebSockets connections,0,5
|
||||
size=Terminal width and height in characters,3,Automatic,5,,,Static (80x24)
|
||||
flavors=Try to enable inbuilt command prompt color customization,1,1-Yes,0-No
|
||||
flavors_envs=Additional enviromental variables to set<br>(in <i>key</i>=<i>value</i> format),9,70,4,\t
|
||||
flavors_cmds=Additional commands to run on shell login,9,70,4,\t
|
||||
rcfile=Execute initialization commands from file,10,0-Shell default,1-Module default,Custom
|
||||
@@ -180,21 +180,6 @@ if ($user eq "root" && $in{'user'}) {
|
||||
my @uinfo = getpwnam($user);
|
||||
@uinfo || &error(&text('index_euser', &html_escape($user)));
|
||||
|
||||
# Terminal flavors (commands)
|
||||
my (@cmds, $term_flavors);
|
||||
if ($config{'flavors'}) {
|
||||
# Bash
|
||||
if ($uinfo[8] =~ /\/bash$/) {
|
||||
my ($cmd_cls, $cmd_lsalias) = ("clear", "alias ls='ls --color=auto'");
|
||||
|
||||
# Pass to run commands directly
|
||||
$term_flavors = "socket.send(\" $cmd_lsalias\\r\"); ".
|
||||
"socket.send(\" $cmd_cls\\r\"); ";
|
||||
# Pass to run commands within theme later
|
||||
push(@cmds, $cmd_lsalias, $cmd_cls);
|
||||
}
|
||||
}
|
||||
|
||||
# Check for directory to start the shell in
|
||||
my $dir = $in{'dir'};
|
||||
|
||||
@@ -237,8 +222,6 @@ my $term_script = <<EOF;
|
||||
new ResizeObserver(function() {
|
||||
fitAddon.fit();
|
||||
}).observe(termcont);
|
||||
|
||||
$term_flavors
|
||||
};
|
||||
socket.onerror = function() {
|
||||
termcont.innerHTML = '<tt style="color: \#ff0000">Error: ' +
|
||||
@@ -263,8 +246,7 @@ if ($xmlhr) {
|
||||
'port' => $port,
|
||||
'cols' => $env_cols,
|
||||
'rows' => $env_rows,
|
||||
'uinfo' => \@uinfo,
|
||||
'cmds' => \@cmds });
|
||||
'uinfo' => \@uinfo });
|
||||
}
|
||||
else {
|
||||
print $term_script;
|
||||
|
||||
@@ -28,135 +28,36 @@ else {
|
||||
&foreign_require("proc");
|
||||
&clean_environment();
|
||||
|
||||
# Terminal inbuilt flavors (envs)
|
||||
my ($shinit);
|
||||
|
||||
# Try to enable shell flavors
|
||||
if ($config{'flavors'}) {
|
||||
|
||||
# Bash
|
||||
if ($uinfo[8] =~ /\/bash$/) {
|
||||
# Optionally add colors to the prompt depending on the user type
|
||||
my $ps1inblt;
|
||||
if ($user eq "root") {
|
||||
# magenta@blue ~# (for root)
|
||||
$ps1inblt = '\[\033[1;35m\]\u\[\033[1;37m\]@'.
|
||||
'\[\033[1;34m\]\h:\[\033[1;37m\]'.
|
||||
'\w\[\033[1;37m\]$\[\033[0m\] ';
|
||||
}
|
||||
else {
|
||||
# green@blue ~$ (for regular users)
|
||||
$ps1inblt = '\[\033[1;32m\]\u\[\033[1;37m\]@'.
|
||||
'\[\033[1;34m\]\h:\[\033[1;37m\]'.
|
||||
'\w\[\033[1;37m\]$\[\033[0m\] ';
|
||||
}
|
||||
# Set shell flavors stuff
|
||||
$shinit = { 'envs' => [ { 'histcontrol' => 'ignoredups:ignorespace' } ],
|
||||
'cmds' => [ { 'ps1' => $ps1inblt } ],
|
||||
'files' => [ '.bashrc', '.profile', '.bash_profile' ] }
|
||||
}
|
||||
# Other shell opts here?
|
||||
}
|
||||
|
||||
# Check user current PS1 and set our default, if allowed
|
||||
if ($shinit) {
|
||||
my ($shfiles, $shcmds) = ($shinit->{'files'},
|
||||
$shinit->{'cmds'});
|
||||
# Check user current PS1
|
||||
my $shparse_opt = sub {
|
||||
my ($line) = @_;
|
||||
my $cmt = index($line, "#");
|
||||
my $eq = index($line, "=");
|
||||
if ($cmt != 0 && $eq >= 0) {
|
||||
my $n = substr($line, 0, $eq);
|
||||
my $v = substr($line, $eq+1);
|
||||
chomp($v);
|
||||
return {$n => $v}
|
||||
}
|
||||
};
|
||||
|
||||
# Does the current user shell have init
|
||||
# files in our internal shell flavors
|
||||
if ($shfiles) {
|
||||
SHFILES:
|
||||
foreach my $shfile (@{$shfiles}) {
|
||||
# Files that are sourced inside of standard
|
||||
# shell init files can contain full path
|
||||
my $shfile_path =
|
||||
$shfile !~ /^\// ? "$uinfo[7]/$shfile" : $shfile;
|
||||
if (-r $shfile_path) {
|
||||
# Read one of the standard shell init files
|
||||
my $shfile_ref = &read_file_lines($shfile_path, 1);
|
||||
foreach my $shfile_line (@$shfile_ref) {
|
||||
my $shfile_line_opt = &$shparse_opt($shfile_line);
|
||||
# Check for an active (not commented)
|
||||
# user-defined PS1 option
|
||||
if ($shfile_line_opt && $shfile_line_opt->{'PS1'}) {
|
||||
# User already have PS1 set, skipping further checks
|
||||
# and disabling internal (our own) PS1 customisations
|
||||
map { $_->{'ps1'} && delete($_->{'ps1'}) } @{$shcmds};
|
||||
last SHFILES;
|
||||
}
|
||||
# Check for other sourced files
|
||||
else {
|
||||
# Perhaps the standard shell init files source other,
|
||||
# files if so we need to add them for a check up too
|
||||
if ($shfile_line =~ /\s*^(?!#)\s*(\.|source)(?<sourced_file>.*)/) {
|
||||
my $sourced_file = "$+{sourced_file}";
|
||||
$sourced_file =~ s/^\s+//;
|
||||
$sourced_file =~ s/\s+$//;
|
||||
$sourced_file =~ s/^\~\///;
|
||||
|
||||
# A file that is being sourced is found, add it
|
||||
# for a check up unless a file already exists in
|
||||
# array and add only if found file us under user
|
||||
# home directory
|
||||
push(@{$shfiles}, $sourced_file)
|
||||
if (!grep(/^$sourced_file$/, @{$shfiles}) &&
|
||||
($sourced_file !~ /^\// ||
|
||||
$sourced_file =~ /^\// &&
|
||||
&is_under_directory($uinfo[7], $sourced_file)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Add additional shell envs from internal
|
||||
# shell flavors if defined for the
|
||||
# current user shell
|
||||
if ($shinit && $shinit->{'envs'}) {
|
||||
foreach my $env (@{$shinit->{'envs'}}) {
|
||||
foreach my $shopt (keys %{$env}) {
|
||||
if ($shopt) {
|
||||
$ENV{uc($shopt)} = $env->{$shopt};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# User defined environmental variables
|
||||
# (in module config) to set
|
||||
if ($config{'flavors_envs'}) {
|
||||
# Admin added to the module config custom
|
||||
# environmental variables, load them now
|
||||
my @flavors_envs = split(/\t+/, $config{'flavors_envs'});
|
||||
foreach my $flavors_env (@flavors_envs) {
|
||||
my ($k, $v) = split(/=/, $flavors_env, 2);
|
||||
$ENV{$k} = $v;
|
||||
}
|
||||
}
|
||||
|
||||
# Set terminal
|
||||
$ENV{'TERM'} = 'xterm-256color';
|
||||
$ENV{'HOME'} = $uinfo[7];
|
||||
chdir($dir || $uinfo[7] || "/");
|
||||
my $shellcmd = $uinfo[8];
|
||||
my $shell = $uinfo[8];
|
||||
$shell =~ s/^.*\///;
|
||||
my $shellname = $shell;
|
||||
$shell = "-".$shell;
|
||||
my ($shellfh, $pid) = &proc::pty_process_exec($uinfo[8], $uid, $gid, $shell);
|
||||
|
||||
# Check for initialization file
|
||||
if ($config{'rcfile'}) {
|
||||
my $rcfile = $config{'rcfile'} == 1 ?
|
||||
# Load shell init default file from module root directory
|
||||
$module_root_directory."/.".$shellname."rc" :
|
||||
# Load shell init custom file
|
||||
$config{'rcfile'};
|
||||
if ($rcfile =~ /^\~\//) {
|
||||
$rcfile =~ s/^\~\///;
|
||||
$rcfile = "$uinfo[7]/$rcfile";
|
||||
}
|
||||
if (-r $rcfile) {
|
||||
# Bash (should add more!)
|
||||
if ($uinfo[8] =~ /\/bash$/) {
|
||||
$shellcmd .= " --rcfile $rcfile";
|
||||
}
|
||||
print STDERR "using alternative shell init file $rcfile\n";
|
||||
}
|
||||
}
|
||||
my ($shellfh, $pid) = &proc::pty_process_exec($shellcmd, $uid, $gid, $shell);
|
||||
&reset_environment();
|
||||
if (!$pid) {
|
||||
&cleanup_miniserv();
|
||||
@@ -164,32 +65,6 @@ if (!$pid) {
|
||||
}
|
||||
print STDERR "shell process is $pid\n";
|
||||
|
||||
# Run additional shell commands from internal
|
||||
# shell flavors, if defined for the current
|
||||
# user shell to run after initial login
|
||||
if ($shinit && $shinit->{'cmds'}) {
|
||||
foreach my $cmd (@{$shinit->{'cmds'}}) {
|
||||
foreach my $shopt (keys %{$cmd}) {
|
||||
if ($shopt) {
|
||||
my $cmdopt = " @{[uc($shopt)]}='$cmd->{$shopt}'\r";
|
||||
syswrite($shellfh, $cmdopt, length($cmdopt));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# User defined commands (in module
|
||||
# config) to run on shell login
|
||||
if ($config{'flavors_cmds'}) {
|
||||
# Admin added to the module config custom
|
||||
# commands to run on shell login, run now
|
||||
my @flavors_cmds = split(/\t+/, $config{'flavors_cmds'});
|
||||
foreach my $flavors_cmd (@flavors_cmds) {
|
||||
my $cmd = " $flavors_cmd\r";
|
||||
syswrite($shellfh, $cmd, length($cmd));
|
||||
}
|
||||
}
|
||||
|
||||
# Detach from controlling terminal
|
||||
if (fork()) {
|
||||
exit(0);
|
||||
|
||||
Reference in New Issue
Block a user