220 lines
8.3 KiB
Bash
220 lines
8.3 KiB
Bash
#!/bin/bash
|
|
# -*- coding: utf-8 -*-
|
|
###########################################################################
|
|
# #
|
|
# envbot - an IRC bot in bash #
|
|
# Copyright (C) 2007-2008 Arvid Norlander #
|
|
# #
|
|
# This program is free software: you can redistribute it and/or modify #
|
|
# it under the terms of the GNU General Public License as published by #
|
|
# the Free Software Foundation, either version 3 of the License, or #
|
|
# (at your option) any later version. #
|
|
# #
|
|
# This program is distributed in the hope that it will be useful, #
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
# GNU General Public License for more details. #
|
|
# #
|
|
# You should have received a copy of the GNU General Public License #
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
# #
|
|
###########################################################################
|
|
#---------------------------------------------------------------------
|
|
## Configuration management
|
|
#---------------------------------------------------------------------
|
|
|
|
#---------------------------------------------------------------------
|
|
## Rehash config file.
|
|
## @Type API
|
|
## @return 0 Success.
|
|
## @return 2 Not same config version.
|
|
## @return 3 Failed to source. The bot should not be in an undefined state.
|
|
## @return 4 Config validation on faked source failed. The bot should not be in an undefined state.
|
|
## @return 5 Failed to source. The bot may be in an undefined state.
|
|
## @Note If config validation fails at REAL source, the bot may quit. However this should never happen.
|
|
#---------------------------------------------------------------------
|
|
config_rehash() {
|
|
local new_conf_ver="$(grep -E '^config_version=' "$config_file")"
|
|
if ! [[ $new_conf_ver =~ ^config_version=$config_current_version ]]; then
|
|
log_error "REHASH: Not same config version. Rehash aborted."
|
|
return 2
|
|
fi
|
|
# Try sourceing in a subshell first to catch errors
|
|
# without causing bot to break
|
|
( source "$config_file" )
|
|
if [[ $? -ne 0 ]]; then
|
|
log_error "REHASH: Failed faked source. Rehash aborted. (TIP: Check for syntax errors in config and any message above this message.)"
|
|
return 3
|
|
fi
|
|
# HACK: Subshell, then unset all but two config_ variables (one is readonly, the other is needed to validate)
|
|
# Then source config file and run validation on it.
|
|
( unset -v $(sed 's/ *config_current_version */ /g;s/ *config_file */ /g' <<<"${!config_*}")
|
|
source "$config_file"
|
|
config_validate && config_validate_transport )
|
|
if [[ $? -ne 0 ]]; then
|
|
log_error "REHASH: Failed config validation on new config. Rehash aborted."
|
|
return 4
|
|
fi
|
|
# Source for real if that worked
|
|
source "$config_file"
|
|
if [[ $? -ne 0 ]]; then
|
|
log_error "REHASH: Failed real source. BOT MAY BE IN UNDEFINED STATE."
|
|
return 5
|
|
fi
|
|
# Lets force command line -v, it may have been overwritten by config.
|
|
if [[ $force_verbose -eq 1 ]]; then
|
|
config_log_stdout='1'
|
|
fi
|
|
local status
|
|
modules_load_from_config
|
|
for module in $modules_loaded; do
|
|
module_${module}_REHASH
|
|
status=$?
|
|
if [[ $status -eq 1 ]]; then
|
|
log_error "Rehash of ${module} failed, trying to unload it."
|
|
modules_unload "${module}" || {
|
|
log_fatal "Unloading of ${module} after failed rehash failed."
|
|
bot_quit "Fatal error in unload of module that failed to rehash"
|
|
}
|
|
fi
|
|
if [[ $status -eq 2 ]]; then
|
|
log_fatal "Rehash of ${module} failed in a FATAL way. Quitting"
|
|
bot_quit "Fatal error in rehash of module"
|
|
fi
|
|
done
|
|
log_info_stdout "Rehash successful"
|
|
}
|
|
|
|
|
|
###########################################################################
|
|
# Internal functions to core or this file below this line! #
|
|
# Module authors: go away #
|
|
###########################################################################
|
|
|
|
#---------------------------------------------------------------------
|
|
## This will call logging if logging is setup,
|
|
## otherwise just print to STDOUT, with prefix
|
|
## @Type Private
|
|
#---------------------------------------------------------------------
|
|
config_dolog_fatal() {
|
|
if [[ $log_file ]]; then
|
|
log_fatal "$1"
|
|
else
|
|
echo "FATAL ERROR: $1"
|
|
fi
|
|
}
|
|
|
|
#---------------------------------------------------------------------
|
|
## Returns an error if the variable in question is empty/not set
|
|
## @Note Works only for non-array variables
|
|
## @Type Private
|
|
## @param Variable name
|
|
## @param Extra error line(s) to append (optional, one parameter for each extra line)
|
|
#---------------------------------------------------------------------
|
|
config_validate_check_exists() {
|
|
if [[ -z "${!1}" ]]; then
|
|
config_dolog_fatal "YOU MUST SET $1 IN THE CONFIG"
|
|
shift
|
|
# Do the rest of the messages
|
|
local line=
|
|
for line in "$@"; do
|
|
config_dolog_fatal "$line"
|
|
done
|
|
envbot_quit 2
|
|
fi
|
|
}
|
|
|
|
|
|
#---------------------------------------------------------------------
|
|
## Validate config file
|
|
## @Type Private
|
|
#---------------------------------------------------------------------
|
|
config_validate() {
|
|
# Note: normal logging is not initialized yet at this point,
|
|
# so we use config_dolog_fatal, that calls normal logging in case
|
|
# logging is loaded (like rehash).
|
|
|
|
# General settings
|
|
config_validate_check_exists config_firstnick
|
|
config_validate_check_exists config_ident
|
|
config_validate_check_exists config_gecos
|
|
|
|
# Server settings
|
|
config_validate_check_exists config_server
|
|
config_validate_check_exists config_server_port
|
|
config_validate_check_exists config_server_ssl
|
|
|
|
# Logging
|
|
config_validate_check_exists config_log_dir
|
|
config_validate_check_exists config_log_stdout
|
|
config_validate_check_exists config_log_raw
|
|
config_validate_check_exists config_log_colors
|
|
|
|
# Commands
|
|
config_validate_check_exists config_commands_listenregex
|
|
config_validate_check_exists config_commands_private_always
|
|
|
|
# Feedback
|
|
config_validate_check_exists config_feedback_unknown_commands
|
|
|
|
# Access
|
|
if [[ -z "${config_access_mask[1]}" ]]; then
|
|
config_dolog_fatal "YOU MUST SET AT LEAST ONE OWNER IN EXAMPLE CONFIG"
|
|
config_dolog_fatal "AND THAT OWNER MUST BE THE FIRST ONE (config_access_mask[1] that is)."
|
|
envbot_quit 1
|
|
fi
|
|
if ! list_contains "config_access_capab[1]" "owner"; then
|
|
config_dolog_fatal "YOU MUST SET AT LEAST ONE OWNER IN EXAMPLE CONFIG"
|
|
config_dolog_fatal "AND THAT OWNER MUST BE THE FIRST ONE (config_access_capab[1] that is)."
|
|
envbot_quit 1
|
|
fi
|
|
|
|
# Transports
|
|
config_validate_check_exists "config_transport_dir"
|
|
if [[ ! -d "${config_transport_dir}" ]]; then
|
|
config_dolog_fatal "The transport directory ${config_transport_dir} doesn't seem to exist"
|
|
envbot_quit 2
|
|
fi
|
|
config_validate_check_exists "config_transport"
|
|
if [[ ! -r "${config_transport_dir}/${config_transport}.sh" ]]; then
|
|
config_dolog_fatal "The transport ${config_transport} doesn't seem to exist"
|
|
envbot_quit 2
|
|
fi
|
|
|
|
# Modules
|
|
config_validate_check_exists config_modules_dir
|
|
if ! [[ -d "$config_modules_dir" ]]; then
|
|
if ! list_contains transport_supports "bind"; then
|
|
config_dolog_fatal "$config_modules_dir DOES NOT EXIST OR IS NOT A DIRECTORY."
|
|
envbot_quit 1
|
|
fi
|
|
fi
|
|
config_validate_check_exists config_modules
|
|
}
|
|
|
|
#---------------------------------------------------------------------
|
|
## Validate some settings from config file that can only be done after
|
|
## transport was loaded.
|
|
## @Type Private
|
|
#---------------------------------------------------------------------
|
|
config_validate_transport() {
|
|
# At this point logging is enabled, we can use it.
|
|
if [[ $config_server_ssl -ne 0 ]]; then
|
|
if ! list_contains transport_supports "ssl"; then
|
|
log_fatal "THIS TRANSPORT DOES NOT SUPORT SSL"
|
|
envbot_quit 1
|
|
fi
|
|
else
|
|
if ! list_contains transport_supports "nossl"; then
|
|
log_fatal "THIS TRANSPORT REQUIRES SSL"
|
|
envbot_quit 1
|
|
fi
|
|
fi
|
|
if [[ "$config_server_bind" ]]; then
|
|
if ! list_contains transport_supports "bind"; then
|
|
log_fatal "THIS TRANSPORT DOES NOT SUPORT BINDING AN IP"
|
|
envbot_quit 1
|
|
fi
|
|
fi
|
|
}
|