Modernize the net handling code

This commit is contained in:
Nick Chambers 2021-11-18 13:56:43 -06:00
parent c33ebdd52c
commit d980e4920f
1 changed files with 69 additions and 46 deletions

115
rowbot
View File

@ -337,6 +337,14 @@ state_resolve() {
fi
}
state_put() {
local ns=${NS-global}
# The `ns_config` variable is a reference to an array
# shellcheck disable=SC2178
declare -n ns_config=__rowbot_state_store_"$ns"
ns_config[$1]=$2
}
state_get() {
local ns=${NS-global}
# The `ns_config` variable is a reference to an array
@ -345,8 +353,16 @@ state_get() {
if [[ -v ns_config[$1] ]]; then
printf %s "${ns_config[$1]}"
if [[ ${ns_config[$1]} = no ]]; then
return 1
fi
elif [[ -v DEFAULT ]]; then
printf %s "$DEFAULT"
if [[ $DEFAULT = no ]]; then
return 1
fi
else
return 1
fi
@ -494,7 +510,7 @@ on_sys_init_010_bootup() {
DEFAULT=yes state_resolve dev
}
on_sys_first_005_bootup() {
on_sys_first_010_bootup() {
log_info "rowbot's pid is %d" "$$"
}
@ -518,13 +534,18 @@ on_sys_exit_999_bootup() {
net_recv() {
declare -n sock_line=$1
# The only possible fail conditions are already checked for.
# shellcheck disable=SC2155
local in_sock=$(NS=net state_get "$in_sock")
IFS= read -ru "$in_sock" "$1"
sock_line=${sock_line%$'\r'}
log_trace "received line: %s" "$sock_line"
}
net_send() {
local fmt
# The only possible fail conditions are already checked for.
# shellcheck disable=SC2155
local fmt out_sock=$(NS=net state_get "$out_sock")
# As this is a printf wrapper, the format string is provided as an argument.
# shellcheck disable=SC2059
printf -v fmt "$1" "${@:2}"
@ -532,83 +553,85 @@ net_send() {
log_trace "sending line: %s" "$fmt"
}
on_sys_init_002_net() {
get_option server irc.libera.chat
get_option tls no
on_sys_init_015_net() {
NS=net DEFAULT=irc.libera.chat state_resolve server
NS=net DEFAULT=no state_resolve tls
if [[ ${config[tls]} = no ]]; then
get_option port 6667
if NS=net state_get tls; then
NS=net DEFAULT=6667 state_resolve port
else
get_option client-cert ""
get_option port 6697
NS=net DEFAULT=6697 state_resolve port
NS=net state_resolve client-cert
fi
}
on_sys_first_002_net() {
local conn_args
on_sys_first_015_net() {
local conn_args irc_sock
# The only possible fail conditions are already checked for.
# shellcheck disable=SC2155
local server=$(NS=net state_get server) port=$(NS=net state_get port)
log_info "rowbot is connecting to %s" "$(url)"
if [[ ${config[tls]} = no ]]; then
exec {irc_sock}<>/dev/tcp/"${config[server]}"/"${config[port]}"
in_sock=$irc_sock out_sock=$irc_sock
if ! NS=net state_get tls; then
exec {irc_sock}<>/dev/tcp/"$server"/"$port"
NS=net state_put in-sock "$irc_sock"
NS=net state_put out-sock "$irc_sock"
else
if ! has socat; then
die "please install socat to use tls with rowbot."
fi
sock_dir=$(mktemp -d)
# The only possible fail conditions are already checked for.
# shellcheck disable=SC2155
local sock_dir=$(mktemp -d)
log_debug "socket directory is %s" "$sock_dir"
NS=net state_put sock-dir "$sock_dir"
mkfifo "$sock_dir"/rowbot-{in,out}.sock
# This is a false positive
# shellcheck disable=SC2102
if [[ ${config[client-cert]} ]]; then
if [[ ! -f ${config[client-cert]} ]]; then
die "client certificate not found: %s" "${config[client-cert]}"
if NS=net state_has client-cert; then
# The only possible fail conditions are already checked for.
# shellcheck disable=SC2155
local client_cert=$(NS=net state_get client-cert)
if [[ ! -f $client_cert ]]; then
die "client certificate not found: %s" "$client_cert"
fi
conn_args=OPENSSL:${config[server]}:${config[port]},cert=${config[client-cert]}
conn_args=OPENSSL:$server:$port,cert=$client_cert
else
conn_args=OPENSSL:${config[server]}:${config[port]}
conn_args=OPENSSL:$server:$port
fi
socat "$conn_args" - <"$sock_dir"/rowbot-in.sock >"$sock_dir"/rowbot-out.sock &
tls_pid=$!
local tls_pid=$! out_sock in_sock
exec {out_sock}>"$sock_dir"/rowbot-in.sock {in_sock}<"$sock_dir"/rowbot-out.sock
NS=net state_put tls-pid "$tls_pid"
NS=net state_put out-sock "$out_sock"
NS=net state_put in-sock "$in_sock"
log_debug "process %d is handling tls" "$tls_pid"
fi
}
on_sys_before_002_net() {
if [[ ${config[tls]} = no ]]; then
export IRC_SOCK=$irc_sock
else
export SOCK_DIR=$sock_dir TLS_PID=$tls_pid
export OUT_SOCK=$out_sock IN_SOCK=$in_sock
fi
}
on_sys_after_002_net() {
if [[ ${config[tls]} = no ]]; then
irc_sock=$IRC_SOCK out_sock=$irc_sock in_sock=$irc_sock
unset IRC_SOCK
else
sock_dir=$SOCK_DIR tls_pid=$TLS_PID out_sock=$OUT_SOCK in_sock=$IN_SOCK
unset SOCK_DIR TLS_PID OUT_SOCK IN_SOCK
fi
}
on_sys_exit_998_net() {
log_info "rowbot is closing the connection to %s" "$(url)"
if [[ ${config[tls]} = no ]]; then
if ! NS=net state_has tls; then
# The only possible fail conditions are already checked for.
# shellcheck disable=SC2155
local irc_sock=$(NS=net state_get in-sock)
exec {irc_sock}>&-
else
if [[ -v tls_pid ]] && is_running "$tls_pid"; then
kill -STOP "$tls_pid"
if NS=net state_has tls-pid; then
# The only possible fail conditions are already checked for.
# shellcheck disable=SC2155
local tls_pid=$(NS=net state_get tls-pid)
if is_running "$tls_pid"; then
kill -STOP "$tls_pid"
fi
fi
rm -rf -- "$sock_dir"
rm -rf -- "$(NS=net state_get sock-dir)"
fi
}