blob: 796470c2721ef85ad7eb7a75742dc86a302fb531 (
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
128
129
130
131
132
133
134
135
|
#!/bin/sh
# mrgrctrnl: configurable ssh tunneler
# Author: Case Duckworth <acdw@acdw.net>
# Version: 0.2
# License: MIT
PRGN="${0##*/}"
usage() {
cat <<END
$PRGN: make magic ssh tunnels
usage: $PRGN [-h] [-k]
$PRGN [-n] [-c CONF | -s SSH]
options:
-h show this help
-k kill all processes and exit
-r restart $PRGN
-n do a dry run: just print what would happen
-c CONFIG use a different CONFIG file instead of
\$XDG_CONFIG_HOME/$PRGN/config
-s CMDLINE directly input an ssh CMDLINE --
don't load the config file.
END
}
# entry point
main() {
__CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/$PRGN/config"
__SSHCMD="-N \"\$user@\$machine\" -L \"\$local:\$remote\""
__PIDF="/tmp/$PRGN.pid"
_run=true
_quiet=false
_use_config=true
while getopts hqkrnc:s: OPT; do
case "$OPT" in
h)
usage
exit 0
;;
q) _quiet=true ;;
k)
tear_down
pkill -x "$PRGN"
exit
;;
r)
tear_down
exec "$PRGN"
;;
n) _run=false ;;
c) __CONFIG="$OPTARG" ;;
s)
__SSHCMD="$OPTARG"
_use_config=false
;;
*)
usage
exit 1
;;
esac
done
if $_use_config && [ ! -r "$__CONFIG" ]; then
echo "!! $PRGN: Cannot find config file '$__CONFIG'."
echo "Aborting."
exit 2
fi
if $_use_config; then
awk '{sub(/#.*$/,"");print}' "$__CONFIG" |
while read -r machine user local remote key rest; do
if [ -z "$machine" ] || [ -z "$user" ] ||
[ -z "$local" ] || [ -z "$remote" ]; then
continue
fi
# shellcheck disable=2030
if [ -n "$key" ]; then
__SSHCMD="$__SSHCMD -i \"$key\""
fi
if [ -n "$rest" ]; then
__SSHCMD="$__SSHCMD $rest"
fi
eval "tunnel $__SSHCMD" &
done
else
# shellcheck disable=2031
eval "tunnel $__SSHCMD" &
fi
wait
}
tunnel() {
# shellcheck disable=2086
$_quiet || echo ssh "$@"
$_run && {
touch "$__PIDF"
while [ -e "$__PIDF" ]; do
grep -q -e "$*" "$__PIDF" && {
sleep 3
continue
}
# shellcheck disable=2015
if ssh "$@" & then
printf '%s\t%s\n' "$!" "$*" >>"$__PIDF"
else
badpid="$!"
kill "$badpid"
sed "/^$badpid/d" "$__PIDF" >"$__PIDF~" &&
mv "$__PIDF~" "$__PIDF"
continue
fi
sleep 3
done
}
}
tear_down() {
printf '%s...' "Killing extant tunnels"
if [ -e "$__PIDF" ]; then
while read -r pid _; do
kill "$pid" 2>/dev/null
done <"$__PIDF"
rm "$__PIDF"
else
pkill -x ssh
fi
echo Done.
}
main "$@"
|