Add support for loading shell initialization file directly

This commit is contained in:
iliajie
2022-11-12 14:31:38 +02:00
parent 1763f9e4cc
commit 1ff0ee36e4
6 changed files with 86 additions and 173 deletions

View File

@@ -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
View 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

View File

@@ -1,2 +1,2 @@
base_port=555
flavors=1
rcfile=1

View File

@@ -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

View File

@@ -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;

View File

@@ -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);