blob: 18e1f3405470d07309ef998e79a3c2dc1dcb72e6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#! /usr/bin/env bash
# Login into a machine.
#
# -c <monitor>
# Execute QEMU 'cont' command in the specified machine monitor UNIX
# socket prior to logging in.
#
# <host> - build host the machine is running on
# <port> - machine's VNC port on the build host
#
usage="usage: $0 [-c <monitor>] <host> <port>"
trap "{ exit 1; }" ERR
set -o errtrace # Trap in functions.
function info () { echo "$*" 1>&2; }
function error () { info "$*"; exit 1; }
mon=
cmd=
while [ "$#" -gt 0 ]; do
case "$1" in
-c)
shift
cmd=cont
mon="$1"
shift
;;
-*)
error "unknown option: $1"
;;
*)
break
;;
esac
done
host="$1"
fport="$2"
if [ -z "$host" -o -z "$fport" ]; then
error "$usage"
fi
if [ -n "$cmd" -a -z "$mon" ]; then
error "$usage"
fi
# Find an unused local port. Surprisingly, it's harder than one would expect.
#
function find_used_ports ()
{
# Use netstat(1) to find the list of port in use.
#
# Proto Recv-Q Send-Q Local Address Foreign Address State
# tcp 0 0 0.0.0.0:139 0.0.0.0:* LISTEN
#
local f="([^[:space:]]+)[[:space:]]+"
netstat --listening --all --tcp --numeric | \
sed -n -re "s/^$f$f$f$f.*$/\4/p" | \
sed -n -re "s/^.+:([0-9]+)$/\1/p" | \
sort --unique --numeric-sort
}
function find_unused_port ()
{
local ups
ups=($(find_used_ports))
local lp up u
for ((lp=49152; lp < 65535; lp++)); do
u=
for up in "${ups[@]}"; do
if [ "$lp" -eq "$up" ]; then
u=true
break
fi
done
if [ ! "$u" ]; then
echo "$lp"
return 0
fi
done
echo "all ports are in use" 1>&2
return 1
}
lport=$(find_unused_port)
# OpenSSH local port forwarding.
#
# ssh -L <localport>:<fowardhost>:<forwardport> <host>
#
# Forward connections on localhost:<localport> to <fowardhost>:<forwardport>
# via <host>.
#
# We are putting OpenSSH to background (-f -N) and then using the "control
# socket" mechanism (-M -S) to terminate it. This also makes sure we don't
# share any existing control sockets that may be set in .ssh/config (e.g.,
# for connection caching/multiplexing).
#
csock="$(mktemp -u)"
ssh -f -N -M -S "$csock" -L "$lport:localhost:$fport" \
-o ExitOnForwardFailure=yes "build@$host"
function exit_trap ()
{
# OpenSSH prints "Exit request sent." regardless of -q.
#
if ! ssh -q -S "$csock" -O exit "build@$host" 2>/dev/null; then
error "unable to terminate background ssh process via $csock"
fi
}
trap exit_trap EXIT
if [ -n "$cmd" ]; then
echo "$cmd" | ssh -S "$csock" "build@$host" socat - "UNIX-CONNECT:$mon"
fi
vinagre "localhost:$lport"
|