This commit is contained in:
Kovid Goyal 2022-03-16 07:02:18 +05:30
commit 0fd7f3f7b5
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 66 additions and 73 deletions

View File

@ -223,13 +223,17 @@ def safe_remove(x: str) -> None:
os.remove(x)
def prepare_script(ans: str, replacements: Dict[str, str]) -> str:
def prepare_script(ans: str, replacements: Dict[str, str], script_type: str) -> str:
for k in ('EXEC_CMD',):
replacements[k] = replacements.get(k, '')
def sub(m: 're.Match[str]') -> str:
return replacements[m.group()]
if script_type == 'sh':
# Remove comments and indents. The dropbear SSH server has 9000 bytes limit on ssh arguments length.
# Needs to be trimmed before replacing EXEC_CMD to avoid affecting the indentation of user commands.
ans = re.sub(r'^[ \t]*#.*$|^[ \t]*', '', ans, flags=re.MULTILINE)
return re.sub('|'.join(fr'\b{k}\b' for k in replacements), sub, ans)
@ -269,7 +273,7 @@ def bootstrap_script(
if request_data:
sd.update(sensitive_data)
replacements.update(sensitive_data)
return prepare_script(ans, sd), replacements, shm
return prepare_script(ans, sd, script_type), replacements, shm
def get_ssh_cli() -> Tuple[Set[str], Set[str]]:

View File

@ -171,6 +171,8 @@ function _set_status_prompt; function fish_prompt; echo -n "$pipestatus $status
pty.send_cmd_to_child('set -q XDG_DATA_DIRS; or echo ok')
pty.wait_till(lambda: pty.screen_contents().count(right_prompt) == 2)
self.ae(str(pty.screen.line(1)), 'ok')
# CWD reporting
self.assertTrue(pty.screen.last_reported_cwd.endswith(self.home_dir))
q = os.path.join(self.home_dir, 'testing-cwd-notification-🐱')
os.mkdir(q)

View File

@ -78,6 +78,12 @@ print(' '.join(map(str, buf)))'''), lines=13, cols=77)
self.ae(parse(conf, '1').env, {'a': 'c', 'b': 'b'})
self.ae(parse(conf, '2').env, {'a': 'c', 'b': 'b'})
def test_ssh_bootstrap_sh_cmd_limit(self):
sh_script, _, _ = bootstrap_script(SSHOptions({'interpreter': 'sh'}), script_type='sh', remote_args=[], request_id='123-123')
rcmd = wrap_bootstrap_script(sh_script, 'sh')
# dropbear has a 9000 bytes maximum command length limit
self.assertLessEqual(sum(len(x) for x in rcmd), 9000)
@property
@lru_cache()
def all_possible_sh(self):

View File

@ -73,7 +73,7 @@ function __ksi_schedule --on-event fish_prompt -d "Setup kitty integration after
if not contains "no-prompt-mark" $_ksi
and not set -q __ksi_prompt_state
function __ksi_mark_prompt_start --on-event fish_prompt
contains "$__ksi_prompt_state" post-exec pre-exec ""
test "$__ksi_prompt_state" != prompt-start
and echo -en "\e]133;D\a"
set --global __ksi_prompt_state prompt-start
echo -en "\e]133;A\a"
@ -97,12 +97,13 @@ function __ksi_schedule --on-event fish_prompt -d "Setup kitty integration after
# Enable CWD reporting
if not contains "no-cwd" $_ksi
# This is actually builtin to fish but stupidly gated on TERM
# https://github.com/fish-shell/fish-shell/blob/master/share/functions/__fish_config_interactive.fish#L257
function __ksi_report_cwd --on-variable PWD --description "Report PWD changes to the terminal"
status --is-command-substitution; and return
echo -en "\e]7;kitty-shell-cwd://$hostname$PWD\a"
# This function name is from fish and will override the builtin one if fish enabled this feature by default.
# We provide this to ensure that fish 3.2.0 and above will work.
# https://github.com/fish-shell/fish-shell/blob/3.2.0/share/functions/__fish_config_interactive.fish#L275
function __update_cwd_osc --on-variable PWD -d "Report PWD changes to kitty"
status is-command-substitution
or echo -en "\e]7;kitty-shell-cwd://$hostname$PWD\a"
end
__ksi_report_cwd
__update_cwd_osc
end
end

View File

@ -21,7 +21,7 @@ data_dir = shell_integration_dir = ''
request_data = int('REQUEST_DATA')
leading_data = b''
HOME = os.path.expanduser('~')
login_shell = pwd.getpwuid(os.geteuid()).pw_shell or 'sh'
login_shell = pwd.getpwuid(os.geteuid()).pw_shell or os.environ.get('SHELL') or 'sh'
def set_echo(fd, on=False):
@ -137,7 +137,13 @@ def compile_terminfo(base):
if not tic:
return
tname = '.terminfo'
q = os.path.join(base, tname, '78', 'xterm-kitty')
if not os.path.exists(q):
os.makedirs(os.path.dirname(q), exist_ok=True)
os.symlink('../x/xterm-kitty', q)
if os.path.exists('/usr/share/misc/terminfo.cdb'):
# NetBSD requires this
os.symlink('../../.terminfo.cdb', os.path.join(base, tname, 'x', 'xterm-kitty'))
tname += '.cdb'
os.environ['TERMINFO'] = os.path.join(HOME, tname)
p = subprocess.Popen(
@ -148,10 +154,6 @@ def compile_terminfo(base):
if rc != 0:
getattr(sys.stderr, 'buffer', sys.stderr).write(p.stdout)
raise SystemExit('Failed to compile the terminfo database')
q = os.path.join(base, tname, '78', 'xterm-kitty')
if not os.path.exists(q):
os.makedirs(os.path.dirname(q), exist_ok=True)
os.symlink('../x/xterm-kitty', q)
def iter_base64_data(f):

View File

@ -88,12 +88,20 @@ mv_files_and_dirs() {
}
compile_terminfo() {
# export TERMINFO
tname=".terminfo"
# Ensure the 78 dir is present
if [ ! -f "$1/$tname/78/xterm-kitty" ]; then
command mkdir -p "$1/$tname/78"
command ln -sf "../x/xterm-kitty" "$1/$tname/78/xterm-kitty"
fi
if [ -e "/usr/share/misc/terminfo.cdb" ]; then
# NetBSD requires this see https://github.com/kovidgoyal/kitty/issues/4622
# NetBSD requires this file, see https://github.com/kovidgoyal/kitty/issues/4622
command ln -sf "../../.terminfo.cdb" "$1/$tname/x/xterm-kitty"
tname=".terminfo.cdb"
fi
# export TERMINFO
export TERMINFO="$HOME/$tname"
# compile terminfo for this system
@ -101,12 +109,6 @@ compile_terminfo() {
tic_out=$(command tic -x -o "$1/$tname" "$1/.terminfo/kitty.terminfo" 2>&1)
[ $? = 0 ] || die "Failed to compile terminfo with err: $tic_out"
fi
# Ensure the 78 dir is present
if [ ! -f "$1/$tname/78/xterm-kitty" ]; then
command mkdir -p "$1/$tname/78"
command ln -sf "../x/xterm-kitty" "$1/$tname/78/xterm-kitty"
fi
}
read_base64_from_tty() {
@ -166,70 +168,43 @@ if [ -n "$leading_data" ]; then
fi
[ -f "$HOME/.terminfo/kitty.terminfo" ] || die "Incomplete extraction of ssh data"
login_shell_is_ok() {
if [ -n "$login_shell" -a -x "$login_shell" ]; then return 0; fi
return 1
}
parse_passwd_record() {
printf "%s" "$(command grep -o '[^:]*$')"
}
using_getent() {
cmd=$(command -v getent)
if [ -n "$cmd" ]; then
output=$(command "$cmd" passwd "$USER" 2>/dev/null)
if [ $? = 0 ]; then
login_shell=$(echo $output | parse_passwd_record)
if login_shell_is_ok; then return 0; fi
fi
fi
login_shell_is_ok() {
[ -n "$1" ] && login_shell=$(echo $1 | parse_passwd_record)
[ -n "$login_shell" -a -x "$login_shell" ] && return 0
return 1
}
using_getent() {
cmd=$(command -v getent) && [ -n "$cmd" ] && output=$(command "$cmd" passwd "$USER" 2>/dev/null) \
&& login_shell_is_ok "$output"
}
using_id() {
cmd=$(command -v id)
if [ -n "$cmd" ]; then
output=$(command "$cmd" -P "$USER" 2>/dev/null)
if [ $? = 0 ]; then
login_shell=$(echo $output | parse_passwd_record)
if login_shell_is_ok; then return 0; fi
fi
fi
return 1
cmd=$(command -v id) && [ -n "$cmd" ] && output=$(command "$cmd" -P "$USER" 2>/dev/null) \
&& login_shell_is_ok "$output"
}
using_python() {
if detect_python; then
output=$(command "$python" -c "import pwd, os; print(pwd.getpwuid(os.geteuid()).pw_shell)")
if [ $? = 0 ]; then
login_shell="$output"
if login_shell_is_ok; then return 0; fi
fi
fi
return 1
detect_python && output=$(command "$python" -c "import pwd, os; print(pwd.getpwuid(os.geteuid()).pw_shell)") \
&& login_shell="$output" && login_shell_is_ok
}
using_perl() {
if detect_perl; then
output=$(command "$perl" -e 'my $shell = (getpwuid($<))[8]; print $shell')
if [ $? = 0 ]; then
login_shell="$output"
if login_shell_is_ok; then return 0; fi
fi
fi
return 1
detect_perl && output=$(command "$perl" -e 'my $shell = (getpwuid($<))[8]; print $shell') \
&& login_shell="$output" && login_shell_is_ok
}
using_passwd() {
if [ -f "/etc/passwd" -a -r "/etc/passwd" ]; then
output=$(command grep "^$USER:" /etc/passwd 2>/dev/null)
if [ $? = 0 ]; then
login_shell=$(echo $output | parse_passwd_record)
if login_shell_is_ok; then return 0; fi
fi
fi
return 1
[ -f "/etc/passwd" -a -r "/etc/passwd" ] && output=$(command grep "^$USER:" /etc/passwd 2>/dev/null) \
&& login_shell_is_ok "$output"
}
using_shell_env() {
[ -n "$SHELL" ] && login_shell="$SHELL" && login_shell_is_ok
}
execute_with_python() {
@ -250,7 +225,7 @@ if [ -n "$KITTY_LOGIN_SHELL" ]; then
login_shell="$KITTY_LOGIN_SHELL"
unset KITTY_LOGIN_SHELL
else
using_getent || using_id || using_python || using_perl || using_passwd || die "Could not detect login shell"
using_getent || using_id || using_python || using_perl || using_passwd || using_shell_env || login_shell="sh"
fi
shell_name=$(command basename $login_shell)
[ -n "$login_cwd" ] && cd "$login_cwd"
@ -270,7 +245,8 @@ exec_zsh_with_integration() {
export ZDOTDIR="$shell_integration_dir/zsh"
exec "$login_shell" "-l"
fi
unset KITTY_ORIG_ZDOTDIR # ensure this is not propagated
# ensure this is not propagated
unset KITTY_ORIG_ZDOTDIR
}
exec_fish_with_integration() {
@ -309,8 +285,10 @@ exec_with_shell_integration() {
}
execute_sh_with_posix_env() {
[ "$shell_name" = "sh" ] || return # only for sh as that is likely to be POSIX compliant
command "$login_shell" -l -c ":" > /dev/null 2> /dev/null && return # sh supports -l so use that
# only for sh as that is likely to be POSIX compliant
[ "$shell_name" = "sh" ] || return
# sh supports -l so use that
command "$login_shell" -l -c ":" > /dev/null 2> /dev/null && return
[ -z "$shell_integration_dir" ] && die "Could not read data over tty ssh kitten cannot function"
sh_dir="$shell_integration_dir/sh"
command mkdir -p "$sh_dir" || die "Creating $sh_dir failed"