From dd4adbba77db09f7835b4802ee5aa8f09db96ff7 Mon Sep 17 00:00:00 2001 From: iliajie Date: Sat, 12 Nov 2022 00:32:04 +0200 Subject: [PATCH] Add respect to shell init files (depending on shell, `bash` only yet) --- xterm/config | 2 +- xterm/config.info | 2 +- xterm/index.cgi | 18 ++++---- xterm/shellserver.pl | 102 +++++++++++++++++++++++++++++++++++-------- 4 files changed, 97 insertions(+), 27 deletions(-) diff --git a/xterm/config b/xterm/config index 3dad60653..957d96c59 100644 --- a/xterm/config +++ b/xterm/config @@ -1,2 +1,2 @@ base_port=555 -flavors=2 \ No newline at end of file +flavors=1 diff --git a/xterm/config.info b/xterm/config.info index 3dd6190bb..779beee4d 100644 --- a/xterm/config.info +++ b/xterm/config.info @@ -1,3 +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=Enable inbuilt command prompt color customization,1,2-Automatic,1-Yes,0-No +flavors=Try to enable inbuilt command prompt color customization,1,1-Yes,0-No diff --git a/xterm/index.cgi b/xterm/index.cgi index 7d0c35a10..447db23e6 100644 --- a/xterm/index.cgi +++ b/xterm/index.cgi @@ -182,15 +182,17 @@ my @uinfo = getpwnam($user); # Terminal flavors (commands) my (@cmds, $term_flavors); -if ($config{'flavors'} == 1 || - $config{'flavors'} == 2 && $uinfo[8] =~ /\/bash$/) { - my ($cmd_cls, $cmd_lsalias) = ("clear", "alias ls='ls --color=auto'"); +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); + # 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 diff --git a/xterm/shellserver.pl b/xterm/shellserver.pl index 388e21bbd..c58af0b7e 100755 --- a/xterm/shellserver.pl +++ b/xterm/shellserver.pl @@ -29,32 +29,88 @@ else { &clean_environment(); # Terminal inbuilt flavors (envs) -if ($config{'flavors'} == 1 || - $config{'flavors'} == 2 && $uinfo[8] =~ /\/bash$/) { +my ($shinit); - # Set shell history controls - $ENV{'HISTCONTROL'} = 'ignoredups:ignorespace'; - - # Set PS1, if flavors are forced or - # skip in auto mode, if already set - if ($config{'flavors'} == 1 || - $config{'flavors'} == 2 && !$ENV{'PS1'}) { - my $ps1; +# 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) - $ps1 = '\[\033[1;35m\]\u\[\033[1;37m\]@'. - '\[\033[1;34m\]\h:\[\033[1;37m\]'. - '\w\[\033[1;37m\]$\[\033[0m\] '; + $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) - $ps1 = '\[\033[1;32m\]\u\[\033[1;37m\]@'. - '\[\033[1;34m\]\h:\[\033[1;37m\]'. - '\w\[\033[1;37m\]$\[\033[0m\] '; + $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} + } + }; + SHFILES: + foreach my $shfile (@{$shfiles}) { + my $shfile_path = + $shfile !~ /^\// ? "$uinfo[7]/$shfile" : $shfile; + if (-r $shfile_path) { + 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 PS1 option + if ($shfile_line_opt && $shfile_line_opt->{'PS1'}) { + map { $_->{'ps1'} && delete($_->{'ps1'}) } @{$shcmds}; + last SHFILES; + } + # Check for other sourced files + else { + if ($shfile_line =~ /\s*^(?!#)\s*(\.|source)(?.*)/) { + my $sourced_file = "$+{sourced_file}"; + $sourced_file =~ s/^\s+//; + $sourced_file =~ s/\s+$//; + $sourced_file =~ s/^\~\///; + push(@{$shfiles}, $sourced_file) + if (!grep(/^$sourced_file$/, @{$shfiles})); + } + } + } + } + } + } + +# Add additional shell envs +if ($shinit && $shinit->{'envs'}) { + foreach my $env (@{$shinit->{'envs'}}) { + foreach my $shopt (keys %{$env}) { + if ($shopt) { + $ENV{uc($shopt)} = $env->{$shopt}; + } } - $ENV{'PS1'} = $ps1; } } @@ -73,6 +129,18 @@ if (!$pid) { } print STDERR "shell process is $pid\n"; +# Add additional shell init commands +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)); + } + } + } + } + # Detach from controlling terminal if (fork()) { exit(0);