Skip to content

Commit b6a9f91

Browse files
committed
Port conductor.sh to posix
1 parent 2808b6a commit b6a9f91

File tree

1 file changed

+50
-39
lines changed

1 file changed

+50
-39
lines changed

ssh-helpers/conductor.sh

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
#!/usr/bin/env bash
1+
#!/usr/bin/sh
22
# Usage:
33
# conductor.sh token
44

5-
set -euo pipefail
6-
75
# Global variables
86
login_shell=""
97
shell_name=""
@@ -32,7 +30,7 @@ die() {
3230
it2ssh_verbose=0
3331

3432
log() {
35-
if [[ $it2ssh_verbose == 0 ]]; then
33+
if [ "$it2ssh_verbose" -eq 0 ]; then
3634
return
3735
fi
3836
printf "[$$] %s: %s\n" $(date +%H:%M:%S) "$*" >> /tmp/it2ssh.log
@@ -63,16 +61,16 @@ first_word() {
6361
drop_first_word() {
6462
local input="$1"
6563
log drop first word from: "$input"
66-
if [[ $input == *" "* ]]; then
64+
if [ "${input#* }" != "$input" ]; then
6765
printf "%s" "${input#* }"
6866
fi
6967
}
7068

71-
if command -v base64 > /dev/null 2> /dev/null; then
69+
if command -v base64 > /dev/null 2>&1; then
7270
log "found base64 command"
7371
base64_encode() { command base64 | command tr -d \\n\\r; }
7472
base64_decode() { command base64 -d; }
75-
elif command -v b64encode > /dev/null 2> /dev/null; then
73+
elif command -v b64encode > /dev/null 2>&1; then
7674
log "found b64encode, b64decode commands"
7775
base64_encode() { command b64encode - | command sed '1d;$d' | command tr -d \\n\\r; }
7876
base64_decode() { command fold -w 76 | command b64decode -r; }
@@ -99,10 +97,10 @@ parse_passwd_record() {
9997
# sets $login_shell as a side effect.
10098
# returns if it looks executable.
10199
login_shell_is_ok() {
102-
log login_shell_is_ok
100+
log login_shell_is_ok with arg "$1"
103101
[ -n "$1" ] && login_shell=$(echo $1 | parse_passwd_record)
104102
[ -n "$login_shell" -a -x "$login_shell" ] && return 0
105-
log "login shell of $login_shell is ok"
103+
log "login shell of $login_shell is bad"
106104
return 1
107105
}
108106

@@ -126,7 +124,7 @@ detect_python() {
126124
[ -z "$python" ] && python=$(command -v python2)
127125
[ -z "$python" ] && python=$(command -v python)
128126
if [ -z "$python" -o ! -x "$python" ]; then python=""; return 1; fi
129-
log no python
127+
log found python at $python
130128
return 0
131129
}
132130

@@ -143,7 +141,7 @@ detect_perl() {
143141
perl_detected="1"
144142
perl=$(command -v perl)
145143
if [ -z "$perl" -o ! -x "$perl" ]; then perl=""; return 1; fi
146-
log no perl
144+
log found perl at $perl
147145
return 0
148146
}
149147

@@ -158,8 +156,8 @@ using_shell_env() {
158156

159157
guess_login_shell() {
160158
[ -n "$login_shell" ] || using_getent || using_id || using_python || using_perl || using_passwd || using_shell_env || login_shell="sh"
161-
printf "%s" ${login_shell}
162-
log login shell is ${login_shell}
159+
printf "%s" "$login_shell"
160+
log login shell is "$login_shell"
163161
}
164162

165163
# Execute login shell
@@ -175,17 +173,17 @@ execute_with_perl() {
175173

176174
execute_with_python() {
177175
if detect_python; then
178-
log execute login shell using python
179-
exec "$perl" "-e" "exec {'$login_shell'} '-$shell_name'"
176+
log execute login shell: "$python" "-c" "import os; os.execlp('$login_shell', '-' '$shell_name')"
180177
exec "$python" "-c" "import os; os.execlp('$login_shell', '-' '$shell_name')"
181178
fi
182179
return 1
183180
}
184181

185182
exec_login_shell() {
186183
local login_shell=${1}
184+
shell_name=$(command basename "$login_shell")
187185

188-
log exec_login_shell "$login_shell"
186+
log exec_login_shell "$login_shell" with name "$shell_name"
189187

190188
# We need to pass the first argument to the executed program with a leading -
191189
# to make sure the shell executes as a login shell. Note that not all shells
@@ -198,6 +196,7 @@ exec_login_shell() {
198196
log failed, just run it with -l
199197
# TODO - this is complicated, come back and do it later.
200198
#execute_sh_with_posix_env
199+
unset RCOUNT
201200
exec "$login_shell" "-l"
202201
log failed completely
203202
printf "%s\n" "Could not execute the shell $login_shell as a login shell" > /dev/stderr
@@ -214,7 +213,7 @@ conductor_cmd_exec_login_shell() {
214213
}
215214

216215
really_exec_login_shell() {
217-
exec_login_shell $(command basename $(guess_login_shell))
216+
exec_login_shell $(guess_login_shell)
218217
}
219218

220219
# Set an environment variable.
@@ -244,24 +243,24 @@ conductor_cmd_runpython() {
244243

245244
really_run_python() {
246245
log really_run_python
247-
rce='
246+
unset RCOUNT
247+
exec python3 << ENDOFSCRIPT
248248
import os
249249
import sys
250250
tty_path = os.ttyname(sys.stdout.fileno())
251251
sys.stdin = open(tty_path, "r")
252252
try:
253-
print(f"\033]135;:{os.getpid()}\033\\\033]135;:end '"$boundary"' r 0\033\\", end="", flush=True)
253+
print(f"\033]135;:{os.getpid()}\033\\\033]135;:end $boundary r 0\033\\\\", end="", flush=True)
254254
program=""
255255
for line in sys.stdin:
256256
if line.rstrip() == "EOF":
257257
exec(program)
258-
print(f"\033]135;:unhook\033\\", end="", flush=True)
258+
print(f"\033]135;:unhook\033\\\\", end="", flush=True)
259259
break
260260
program += line
261261
except Exception as e:
262262
print(e)
263-
'
264-
exec python3 <<< "$rce"
263+
ENDOFSCRIPT
265264
log "unexpected return from exec"
266265
exit 0
267266
}
@@ -275,20 +274,21 @@ really_run() {
275274
fi
276275
log exec "$SHELL" -c "$*"
277276
printf "\e]135;:"
277+
unset RCOUNT
278278
exec "$SHELL" -c "$*"
279279
printf "\e\\"
280280
}
281281

282282
conductor_cmd_shell() {
283283
log conductor_cmd_shell
284-
if [ "$#" -lt 2 ]; then
284+
if [ "$#" -lt 1 ]; then
285285
log bad args
286286
(exit 1)
287287
return
288288
fi
289289
printf "\e]135;:"
290290
set +e
291-
set +o pipefail
291+
log will run $*
292292
$*
293293
printf "\e\\"
294294
}
@@ -357,8 +357,9 @@ conductor_cmd_eval() {
357357
local mydir=$(mktemp -d "${TMPDIR:-/tmp/}it2ssh.XXXXXXXXXXXX")
358358
local file="$mydir/it2ssh-eval"
359359
log "mydir=$mydir tmpdir=${TMPDIR:-/tmp/} file=$file"
360-
base64_decode <<< "$b64" > "$file"
361-
source "$file"
360+
printf "%s" "$b64" | base64_decode > "$file"
361+
log will source "$file" with content $(cat "$file")
362+
. "$file"
362363
rm -f "$file"
363364
log "$file" finished executing
364365
}
@@ -370,6 +371,17 @@ write() {
370371
# Main Loop
371372
################################################################################
372373

374+
randomnumber() {
375+
if [ -z "${RCOUNT}" ]; then
376+
export RCOUNT=0
377+
else
378+
export RCOUNT=$((RCOUNT + 1))
379+
fi
380+
381+
printf "%s." $RCOUNT
382+
awk 'BEGIN { srand(); print int(rand() * 65536)""int(rand() * 65536)""int(rand() * 65536)""int(rand() * 65536) }'
383+
}
384+
373385
handle_command() {
374386
local unparsed=${1}
375387

@@ -380,39 +392,38 @@ handle_command() {
380392
local args=$(drop_first_word "${unparsed}")
381393
log args is $args
382394

383-
local boundary="${RANDOM}${RANDOM}${RANDOM}${RANDOM}"
395+
local boundary=$(randomnumber)
384396
write begin $boundary
385397
log invoke $cmd_name with arguments $args
386398
set +e
387-
set +o pipefail
388-
if [[ $(type -t conductor_cmd_${cmd_name}) == function ]]; then
399+
if ( LC_ALL=C type conductor_cmd_${cmd_name} 2>/dev/null | head -n 1 | grep -q function ); then
389400
conductor_cmd_${cmd_name} $args
390401
else
391402
write "bad command ${cmd_name}"
392403
false
393404
fi
394-
if [[ $run_python == 1 ]]; then
405+
if [ $run_python = 1 ]; then
395406
really_run_python "$boundary"
396407
fi
397408
write end $boundary $? r
398-
if [[ $quit == 1 ]]; then
409+
if [ $quit = 1 ]; then
410+
log quitting
399411
exit 0
400412
fi
401-
if [[ $exec_shell == 1 ]]; then
413+
if [ $exec_shell = 1 ]; then
402414
log successfully executed the login shell. Unhook.
403415
write unhook
404416
cleanup
405417
really_exec_login_shell
406418
fi
407-
if [[ $run_cmd == 1 ]]; then
419+
if [ $run_cmd = 1 ]; then
408420
log successfully ran a command. Unhook.
409421
write unhook
410422
cleanup
411423
really_run $args
412424
fi
413425

414426
set -e
415-
set -o pipefail
416427
}
417428

418429
iterate() {
@@ -438,7 +449,7 @@ drain_stdin() {
438449
while :
439450
do
440451
key="$(printf x; dd bs=1 count=1 2> /dev/null; printf x)"
441-
if [[ "$key" == "xx" ]]; then
452+
if [ "$key" = "xx" ]; then
442453
log "done draining"
443454
break
444455
fi
@@ -448,10 +459,10 @@ drain_stdin() {
448459
}
449460

450461
main() {
451-
local token=$(base64_decode <<< $1)
452-
local uniqueid=$(base64_decode <<< $2)
453-
local booleanargs=$(base64_decode <<< $3)
454-
local sshargs=$(base64_decode <<< $4)
462+
local token=$(printf "%s" "$1" | base64_decode)
463+
local uniqueid=$(printf "%s" "$2" | base64_decode)
464+
local booleanargs=$(printf "%s" "$3" | base64_decode)
465+
local sshargs=$(printf "%s" "$4" | base64_decode)
455466

456467
log starting with token $token
457468
log $(env)

0 commit comments

Comments
 (0)