#!/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 . # # # ########################################################################### #--------------------------------------------------------------------- ## Misc functions. #--------------------------------------------------------------------- # Some codes for IRC formatting #--------------------------------------------------------------------- ## IRC formatting: Bold ## @Type API #--------------------------------------------------------------------- format_bold=$'\002' #--------------------------------------------------------------------- ## IRC formatting: Underline ## @Type API #--------------------------------------------------------------------- format_underline=$'\037' #--------------------------------------------------------------------- ## IRC formatting: Color ## @Type API #--------------------------------------------------------------------- format_color=$'\003' #--------------------------------------------------------------------- ## IRC formatting: Inverse ## @Type API #--------------------------------------------------------------------- format_inverse=$'\026' #--------------------------------------------------------------------- ## IRC formatting: Restore to normal ## @Type API #--------------------------------------------------------------------- format_normal=$'\017' #--------------------------------------------------------------------- ## IRC formatting: ASCII bell ## Please. Don't. Abuse. This. ## @Type API #--------------------------------------------------------------------- format_bell=$'\007' # Color table: # white 0 # black 1 # blue 2 # green 3 # red 4 # darkred 5 # purple 6 # darkyellow 7 # yellow 8 # brightgreen 9 # darkaqua 10 # aqua 11 # lightblue 12 # brightpurple 13 # darkgrey 14 # lightgrey 15 #--------------------------------------------------------------------- ## This will add colors around this text. ## @Type API ## @param Foreground color ## @param Background color ## @param String to colorise #--------------------------------------------------------------------- format_colorise() { echo "${format_color}${1},${2}${3}${format_normal}" } #--------------------------------------------------------------------- ## Quits the bot in a graceful way. ## @Type API ## @param Reason to quit (optional) ## @param Return status (optional, if not given, then exit 0). #--------------------------------------------------------------------- bot_quit() { # Yes this function is odd but there is a reason. # If this is called from a trap like Ctrl-C we must be able to # resume. # Keep track of in what state we are while true; do case "$envbot_quitting" in 0) for module in $modules_before_disconnect; do module_${module}_before_disconnect done (( envbot_quitting++ )) ;; 1) local reason="$1" send_quit "$reason" sleep 1 (( envbot_quitting++ )) ;; 2) server_connected=0 for module in $modules_after_disconnect; do module_${module}_after_disconnect done (( envbot_quitting++ )) ;; 3) for module in $modules_FINALISE; do module_${module}_FINALISE done (( envbot_quitting++ )) ;; 4) log_info_stdout "Bot quit gracefully" transport_disconnect (( envbot_quitting++ )) ;; # -1 is before main loop entered, # may happen during module loading 5|-1) rm -rvf "$tmp_home" if [[ $2 ]]; then exit $2 else exit 0 fi ;; *) log_error "Um. bot_quit() and envbot_quitting is $envbot_quitting. This shouldn't happen." log_error "Please report a bug including the last 40 lines or so of log and what you did to cause it." # Quit and clean up temp files. envbot_quit 2 ;; esac done } #--------------------------------------------------------------------- ## Restart the bot in a graceful way. I hope. ## @Type API ## @param Reason to restart (optional) #--------------------------------------------------------------------- bot_restart() { for module in $modules_before_disconnect; do module_${module}_before_disconnect done local reason="$1" send_quit "$reason" sleep 1 server_connected=0 for module in $modules_after_disconnect; do module_${module}_after_disconnect done for module in $modules_FINALISE; do module_${module}_FINALISE done log_info_stdout "Bot quit gracefully" transport_disconnect rm -rvf "$tmp_home" exec env -i TERM="$TERM" "$(type -p bash)" $0 "${command_line[@]}" } #--------------------------------------------------------------------- ## Strip leading/trailing spaces. ## @Type API ## @Note Before this function was deprecated, but it has been recoded ## @Note in a much faster way. This version is not compatible with old ## @Note version. ## @param String to strip ## @param Variable to return in #--------------------------------------------------------------------- misc_clean_spaces() { # Fastest way that is still secure local array read -ra array <<< "$1" printf -v "$2" '%s' "${array[*]}" } #--------------------------------------------------------------------- ## Strip leading/trailing separator. ## @Type API ## @param String to strip ## @param Variable to return in ## @param Separator #--------------------------------------------------------------------- misc_clean_delimiter() { local sep="$3" array local IFS="$sep" # Fastest way that is still secure read -ra array <<< "$1" local tmp="${array[*]}" printf -v "$2" '%s' "${tmp#${sep}}" } #--------------------------------------------------------------------- ## Remove a value from a space (or other delimiter) separated list. ## @Type API ## @param List to remove from. ## @param Value to remove. ## @param Variable to return new list in. ## @param Separator (optional, defaults to space) #--------------------------------------------------------------------- list_remove() { local sep=${4:-" "} local oldlist="${sep}${!1}${sep}" local newlist="${oldlist//${sep}${2}${sep}/${sep}}" misc_clean_delimiter "$newlist" "$3" "$sep" # Get rid of the unneeded spaces. } #--------------------------------------------------------------------- ## Checks if a space separated list contains a value. ## @Type API ## @param List to check. ## @param Value to check for. ## @return 0 If found. ## @return 1 If not found. #--------------------------------------------------------------------- list_contains() { [[ " ${!1} " = *" $2 "* ]] } ########################################################################### # Internal functions to core or this file below this line! # # Module authors: go away # ########################################################################### #--------------------------------------------------------------------- ## Like debug_assert_argc but works without debugging on. ## For use in sensitive functions in core. ## @Type Private ## @param Minimum count of parameters ## @param Maximum count of parameters ## @param All the rest of the parameters as "$@" ## @Example For example this could be called as: ## @Example
## @Example foo() {
## @Example   security_assert_argc 2 2 "$@"
## @Example   ... rest of function ...
## @Example }
## @Example 
#--------------------------------------------------------------------- security_assert_argc() { local min="$1" max="$2" shift 2 if [[ $# -lt $min || $# -gt $max ]]; then log_error "Security sensitive function ${FUNCNAME[1]} should have had between $min and $max parameters but had $# instead." log_error "Security sensitive function ${FUNCNAME[1]} was called from ${BASH_SOURCE[2]}:${BASH_LINENO[1]} ${FUNCNAME[2]} with these parameters: $*" log_error "This should be reported as a bug." return 1 fi return 0 }