diff --git a/rowbot b/rowbot index 7b50e8e..295d5ac 100755 --- a/rowbot +++ b/rowbot @@ -35,6 +35,7 @@ error() { # argument parser for parsing arguments ## +original_args=("$0" "$@") declare -A opts while (( $# )); do @@ -80,28 +81,71 @@ else port=${opts[port]:-6667} fi -level=${opts[log-level]:-info} - -if [[ ${opts[log]} ]]; then - exec {log}>"${opts[log]}" -else - log=1 -fi - nick=${opts[nick]:-rowbot-dev} ident=${opts[ident]:-rowbot} realname=${opts[realname]:-rowbot} chan=${opts[chan]:-} trigger=${opts[trigger]:-\`} fact_root=${opts[fact-root]:-.} +reload=${opts[reload]:-no} +dev=${opts[dev]:-no} + +if [[ -v USER ]]; then + owner=${opts[owner]:-"$USER"} +else + owner=${opts[owner]:-uplime} +fi + +level=${opts[log-level]:-info} + +if [[ $reload = yes ]]; then + log=$LOG_FD +elif [[ ${opts[log]} ]]; then + exec {log}>"${opts[log]}" +else + log=1 +fi + +### +# utilities +### + +cleanup() { + exec {in_sock}>&- {out_sock}>&- {log}>&- + + if [[ $tls = yes ]]; then + kill "$tls_pid" + rm -rf "$sock_dir" + fi + + if [[ -v ping_pid ]]; then + kill "$ping_pid" + fi +} + +trap cleanup EXIT ### # net code ### -if [[ $tls = yes ]]; then - coproc sock { socat OPENSSL:"$server":"$port" -; } - exec {in_sock}<&"${sock[0]}" {out_sock}>&"${sock[1]}" +if [[ $reload = yes ]]; then + in_sock=$IN_SOCK out_sock=$OUT_SOCK + + if [[ $tls = yes ]]; then + sock_dir=$SOCK_DIR + tls_pid=$tls_pid + fi + + if [[ -v PING_PID ]]; then + ping_pid=$PING_PID + fi +elif [[ $tls = yes ]]; then + sock_dir=$(mktemp -d) + mkfifo "$sock_dir"/rb{in,out} + socat OPENSSL:"$server":"$port" - <"$sock_dir"/rbin >"$sock_dir"/rbout & + tls_pid=$! + exec {out_sock}>"$sock_dir"/rbin {in_sock}<"$sock_dir"/rbout else exec {sock}<>/dev/tcp/"$server"/"$port" in_sock=$sock out_sock=$sock @@ -175,7 +219,7 @@ on_001() { sleep 10 done & - trap "kill $!" EXIT + ping_pid=$! } on_002() { @@ -291,6 +335,7 @@ pong() { privmsg() { send "PRIVMSG %s :\u200b%s" "$1" "$2" + info "<%s/%s> %s" "$nick" "$1" "$2" } user() { @@ -301,7 +346,7 @@ user() { # app hooks ## -hook_PRIVMSG_factoids() { +hook_post_PRIVMSG_factoids() { if [[ ${params[0]:0:1} != \# ]]; then return 0 elif [[ ${words[0]} = "$trigger"* ]]; then @@ -348,12 +393,55 @@ hook_PRIVMSG_factoids() { fi } +hook_post_PRIVMSG_control_panel() { + if [[ ${words[0]} = "$trigger"* ]]; then + if [[ $from != $owner && $dev != yes ]]; then + return 0 + fi + + local to=${params[0]} + + if [[ ${params[0]:0:1} != \# ]]; then + to=$from + fi + + case ${words[0]:${#trigger}} in + raw) + local cmd + cmd=${params[1]#*"$trigger"raw} cmd=${cmd# } + info "%s is executing command: %s" "$from" "$cmd" + send "$cmd" + ;; + join) + join "${words[1]}" + ;; + reload) + export IN_SOCK=$in_sock OUT_SOCK=$out_sock LOG_FD=$log + + if [[ -v tls_pid ]]; then + export SOCK_DIR=$sock_dir + export TLS_PID=$tls_pid + fi + + if [[ -v ping_pid ]]; then + export PING_pid=$ping_pid + fi + + privmsg "$to" "reloading..." + exec "${original_args[@]}" --reload + ;; + esac + fi +} + ### # driver ### -nick "$nick" -user "$ident" "$realname" +if [[ $reload != yes ]]; then + nick "$nick" + user "$ident" "$realname" +fi while recv line; do params=( ) @@ -389,13 +477,24 @@ while recv line; do words=( ) fi + skip_handler=0 + while IFS= read -r hook; do "$hook" - done < <(compgen -A function "hook_${cmd^^}_") + (( skip_handler |= $? )) + done < <(compgen -A function "hook_pre_${cmd^^}_") if hash "on_${cmd^^}" 2>/dev/null; then - "on_${cmd^^}" + if (( ! skip_handler )); then + "on_${cmd^^}" + else + debug "handler for %s was skipped" "${cmd^^}" + fi else warn "unhandled line: %s" "$orig_line" fi + + while IFS= read -r hook; do + "$hook" + done < <(compgen -A function "hook_post_${cmd^^}_") done