Implement an IRC parser, and make net connections reloadable
This commit is contained in:
parent
6164d713df
commit
f7c146b556
1 changed files with 120 additions and 9 deletions
129
rowbot
129
rowbot
|
@ -162,6 +162,33 @@ on_sys_first_001_bootup() {
|
||||||
log_info "rowbot's pid is %d" "$$"
|
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() {
|
on_sys_exit_999_bootup() {
|
||||||
log_info "There’s a lot of beauty in ordinary things. Isn’t that kind of the point?"
|
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
|
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() {
|
on_sys_exit_999_log() {
|
||||||
if [[ -v log_fd ]] && (( log_fd != 1 )); then
|
if [[ -v log_fd ]] && (( log_fd != 1 )); then
|
||||||
log_debug "shutting logger down"
|
log_debug "shutting logger down for good"
|
||||||
exec {log_fd}>&-
|
exec {log_fd}>&-
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -302,6 +336,25 @@ on_sys_first_002_net() {
|
||||||
fi
|
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() {
|
on_sys_exit_998_net() {
|
||||||
if [[ ${config[tls]} = no ]]; then
|
if [[ ${config[tls]} = no ]]; then
|
||||||
log_info "rowbot is closing the connection to irc://%s:%s" "${config[server]}" "${config[port]}"
|
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
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
# irc send handlers
|
||||||
|
###
|
||||||
|
|
||||||
|
nick() {
|
||||||
|
net_send "NICK :%s" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
user() {
|
||||||
|
net_send "USER %s 0 * :%s" "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
###
|
###
|
||||||
# cleanup
|
# cleanup
|
||||||
###
|
###
|
||||||
|
@ -333,16 +398,9 @@ trap cleanup EXIT
|
||||||
###
|
###
|
||||||
|
|
||||||
reload_config() {
|
reload_config() {
|
||||||
local setting setting_name
|
|
||||||
run_callbacks on_sys_before_
|
run_callbacks on_sys_before_
|
||||||
run_callbacks on_before_
|
run_callbacks on_before_
|
||||||
|
RELOADED=yes exec "${cmd_line[@]}"
|
||||||
for setting in "${!config[@]}"; do
|
|
||||||
setting_name=${setting//-/_}
|
|
||||||
export "${setting_name^^}"="${config[$setting]}"
|
|
||||||
done
|
|
||||||
|
|
||||||
exec "${cmd_line[@]}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reload_hup() {
|
reload_hup() {
|
||||||
|
@ -366,3 +424,56 @@ else
|
||||||
run_callbacks on_sys_first_
|
run_callbacks on_sys_first_
|
||||||
run_callbacks on_first_
|
run_callbacks on_first_
|
||||||
fi
|
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 a new issue