Implement an IRC parser, and make net connections reloadable
This commit is contained in:
parent
6164d713df
commit
f7c146b556
129
rowbot
129
rowbot
|
@ -162,6 +162,33 @@ on_sys_first_001_bootup() {
|
|||
log_info "rowbot's pid is %d" "$$"
|
||||
}
|
||||
|
||||
on_sys_first_999_bootup() {
|
||||
log_debug "registering with the server"
|
||||
nick "${config[nick]}"
|
||||
user "${config[ident]}" "${config[realname]}"
|
||||
}
|
||||
|
||||
on_sys_before_999_bootup() {
|
||||
local setting setting_name
|
||||
log_debug "storing the config"
|
||||
|
||||
for setting in "${!config[@]}"; do
|
||||
setting_name=${setting//-/_}
|
||||
export "CONFIG_${setting_name^^}=${config[$setting]}"
|
||||
done
|
||||
}
|
||||
|
||||
on_sys_after_001_bootup() {
|
||||
log_debug "reloading the config"
|
||||
local setting setting_name
|
||||
|
||||
while IFS= read -r setting; do
|
||||
setting_name=${setting#CONFIG_} setting_name=${setting_name//_/-}
|
||||
config[${setting_name,,}]=${!setting}
|
||||
unset "$setting"
|
||||
done < <(compgen -e CONFIG_)
|
||||
}
|
||||
|
||||
on_sys_exit_999_bootup() {
|
||||
log_info "There’s a lot of beauty in ordinary things. Isn’t that kind of the point?"
|
||||
}
|
||||
|
@ -227,9 +254,16 @@ on_sys_init_001_log() {
|
|||
fi
|
||||
}
|
||||
|
||||
on_sys_before_999_log() {
|
||||
if [[ -v log_fd ]] && (( log_fd != 1 )); then
|
||||
log_debug "shutting logger down for reload"
|
||||
exec {log_fd}>&-
|
||||
fi
|
||||
}
|
||||
|
||||
on_sys_exit_999_log() {
|
||||
if [[ -v log_fd ]] && (( log_fd != 1 )); then
|
||||
log_debug "shutting logger down"
|
||||
log_debug "shutting logger down for good"
|
||||
exec {log_fd}>&-
|
||||
fi
|
||||
}
|
||||
|
@ -302,6 +336,25 @@ on_sys_first_002_net() {
|
|||
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() {
|
||||
if [[ ${config[tls]} = no ]]; then
|
||||
log_info "rowbot is closing the connection to irc://%s:%s" "${config[server]}" "${config[port]}"
|
||||
|
@ -317,6 +370,18 @@ on_sys_exit_998_net() {
|
|||
fi
|
||||
}
|
||||
|
||||
###
|
||||
# irc send handlers
|
||||
###
|
||||
|
||||
nick() {
|
||||
net_send "NICK :%s" "$1"
|
||||
}
|
||||
|
||||
user() {
|
||||
net_send "USER %s 0 * :%s" "$1" "$2"
|
||||
}
|
||||
|
||||
###
|
||||
# cleanup
|
||||
###
|
||||
|
@ -333,16 +398,9 @@ trap cleanup EXIT
|
|||
###
|
||||
|
||||
reload_config() {
|
||||
local setting setting_name
|
||||
run_callbacks on_sys_before_
|
||||
run_callbacks on_before_
|
||||
|
||||
for setting in "${!config[@]}"; do
|
||||
setting_name=${setting//-/_}
|
||||
export "${setting_name^^}"="${config[$setting]}"
|
||||
done
|
||||
|
||||
exec "${cmd_line[@]}"
|
||||
RELOADED=yes exec "${cmd_line[@]}"
|
||||
}
|
||||
|
||||
reload_hup() {
|
||||
|
@ -366,3 +424,56 @@ else
|
|||
run_callbacks on_sys_first_
|
||||
run_callbacks on_first_
|
||||
fi
|
||||
|
||||
###
|
||||
# driver/protocol parser
|
||||
###
|
||||
|
||||
while net_recv line; do
|
||||
declare -A msg=([words]=no [original]="$line")
|
||||
|
||||
# parse prefix in the style of nick!ident@host
|
||||
|
||||
if [[ ${line:0:1} = :* ]]; then
|
||||
prefix=${line%% *} prefix=${prefix#:} line=${line#:"$prefix"} line=${line# }
|
||||
log_debug "parsing message prefix %s" "$prefix"
|
||||
msg[host]=${prefix#*@} prefix=${prefix%"${msg[host]}"} prefix=${prefix%@}
|
||||
|
||||
if [[ $prefix ]]; then
|
||||
msg[ident]=${prefix#*!}
|
||||
|
||||
if [[ ${msg[ident]} != "$prefix" ]]; then
|
||||
msg[nick]=${prefix%!*}
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# parse command formatted as a 3 digit integer or as a word consisting of
|
||||
# alphabet values
|
||||
|
||||
msg[cmd]=${line%% *} line=${line#"${msg[cmd]}"} line=${line# }
|
||||
log_debug "parsing message command %s" "${msg[cmd]}"
|
||||
|
||||
# parse the remaining values into white-space separated arguments
|
||||
|
||||
msg_args=()
|
||||
|
||||
while [[ $line ]]; do
|
||||
if [[ ${line:0:1} = : ]]; then
|
||||
msg_args+=( "${line:1}" ) msg[words]=yes line=
|
||||
# Code using this array will be implemented later.
|
||||
# shellcheck disable=SC2034
|
||||
read -ra msg_words <<< "${msg_args[-1]}"
|
||||
log_debug "parsed final argument %s" "${msg_args[-1]}"
|
||||
else
|
||||
arg=${line%% *} msg_args+=( "$arg" ) line=${line#"$arg"} line=${line# }
|
||||
log_debug "parsed argument %s" "$arg"
|
||||
fi
|
||||
done
|
||||
|
||||
if has irc_on_"${msg[cmd]^^}"; then
|
||||
irc_on_"${msg[cmd]^^}"
|
||||
else
|
||||
log_warn "unhandled line: %s" "${msg[original]}"
|
||||
fi
|
||||
done
|
||||
|
|
Loading…
Reference in New Issue