From 1ff0ee36e4f4459633ad16a20dade566f4b1502b Mon Sep 17 00:00:00 2001 From: iliajie Date: Sat, 12 Nov 2022 14:31:38 +0200 Subject: [PATCH] Add support for loading shell initialization file directly --- proc/proc-lib.pl | 4 +- xterm/.bashrc | 58 +++++++++++++++ xterm/config | 2 +- xterm/config.info | 4 +- xterm/index.cgi | 20 +---- xterm/shellserver.pl | 171 ++++++------------------------------------- 6 files changed, 86 insertions(+), 173 deletions(-) create mode 100644 xterm/.bashrc diff --git a/proc/proc-lib.pl b/proc/proc-lib.pl index 703fb3de2..9a6a5ad32 100755 --- a/proc/proc-lib.pl +++ b/proc/proc-lib.pl @@ -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); diff --git a/xterm/.bashrc b/xterm/.bashrc new file mode 100644 index 000000000..3f6b34892 --- /dev/null +++ b/xterm/.bashrc @@ -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 diff --git a/xterm/config b/xterm/config index 957d96c59..b0f69d636 100644 --- a/xterm/config +++ b/xterm/config @@ -1,2 +1,2 @@ base_port=555 -flavors=1 +rcfile=1 \ No newline at end of file diff --git a/xterm/config.info b/xterm/config.info index 86cccc5e4..e95d2bb0e 100644 --- a/xterm/config.info +++ b/xterm/config.info @@ -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
(in key=value 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 \ No newline at end of file diff --git a/xterm/index.cgi b/xterm/index.cgi index fd3d2263c..4d2af5f8f 100644 --- a/xterm/index.cgi +++ b/xterm/index.cgi @@ -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 = < $port, 'cols' => $env_cols, 'rows' => $env_rows, - 'uinfo' => \@uinfo, - 'cmds' => \@cmds }); + 'uinfo' => \@uinfo }); } else { print $term_script; diff --git a/xterm/shellserver.pl b/xterm/shellserver.pl index 1d542d60d..c7cdaf181 100755 --- a/xterm/shellserver.pl +++ b/xterm/shellserver.pl @@ -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)(?.*)/) { - 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);