rowbot/rowbot

159 lines
2.3 KiB
Bash
Executable File

#!/usr/bin/env bash
###
# logger
###
declare -A levels=(
[debug]=1 [info]=2
[warn]=3 [error]=4
)
log() {
if [[ -v LEVEL ]] && (( levels[$level] <= levels[$LEVEL] )); then
printf "%s: $1\n" "${LEVEL^^}" "${@:2}" >&"$log"
fi
}
debug() {
LEVEL=debug log "$@"
}
info() {
LEVEL=info log "$@"
}
warn() {
LEVEL=warn log "$@"
}
error() {
LEVEL=error log "$@"
}
###
# argument parser for parsing arguments
##
declare -A opts
while (( $# )); do
case $1 in
--*=*)
key=${1#--} key=${key%%=*}
opts[$key]=${1#--*=}
;;
--no-*)
key=${1#--no-}
opts[$key]=no
;;
--)
shift
break
;;
--*)
key=${1#--}
opts[$key]=yes
;;
*)
break
esac
shift
done
###
# default config
##
server=${opts[server]:-irc.libera.chat}
tls=${opts[tls]:-no}
if [[ $tls = yes ]]; then
if ! hash socat 2>/dev/null; then
printf 'please install socat to use tls with rowbot.\n' >&2
exit 1
fi
port=${opts[port]:-6697}
else
port=${opts[port]:-6667}
fi
level=${opts[log-level]:-info}
if [[ ${opts[log]} ]]; then
exec {log}>"${opts[log]}"
else
log=1
fi
###
# net code
###
if [[ $tls = yes ]]; then
coproc sock { socat OPENSSL:"$server":"$port" -; }
in_sock=${sock[0]} out_sock=${sock[1]}
else
exec {sock}<>/dev/tcp/"$server"/"$port"
in_sock=$sock out_sock=$sock
fi
send() {
local fmt
printf -v fmt "$1" "${@:2}"
printf '%s\r\n' "$fmt" >&"$out_sock"
}
recv() {
declare -n sock_line=$1
IFS= read -r "$1" <&"$in_sock"
sock_line=${sock_line%$'\r'}
}
###
# driver
###
while recv line; do
params=( )
has_words=no
orig_line=$line
if [[ ${line:0:1} = : ]]; then
src=${line%% *} src=${src#:}
line=${line#:"$src"} line=${line# }
from=${src%@*} ident=${from#*!}
from=${from%!*} host=${src#*@}
fi
cmd=${line%% *}
line=${line#"$cmd"}
line=${line# }
while [[ $line ]]; do
if [[ ${line:0:1} = : ]]; then
params+=("${line:1}")
line=""
has_words=yes
else
param=${line%% *}
params+=("$param")
line=${line#"$param"} line=${line# }
fi
done
if [[ $has_words = yes ]]; then
read -ra words <<< "${params[@]:(-1)}"
else
words=( )
fi
if hash "on_${cmd^^}" 2>/dev/null; then
"on_${cmd^^}"
else
warn "unhandled line: %s" "$orig_line"
fi
done