#!/bin/bash# MBB - MyBashBot# ChangeLog see file CHANGELOG included in distribution### LOCATION OF THE CONFIGFILE ####export MBB_CONFIG="/home/bonsai/etc/mbb.conf"export MBB_CONFIG="/home/bonsai/devel/bash-scripts/irc-bot/MyBashBot/mbb.conf"### ERROR CODES ###export ERR_MBB_NOERR=0export ERR_MBB_CFG_NXFILE=100export ERR_MBB_CFG_NXKEYWORD=101export ERR_MBB_CMDPLGIN_NOPLUGIN=110function _mbb_getconfentry(){ local KEYWORD="$1" ### check if $MBB_CONFIG is a valid file, else return if [ ! -e "$MBB_CONFIG" ]; then return $ERR_MBB_CFG_NXFILE fi if (grep -i "^${KEYWORD} " ${MBB_CONFIG} >/dev/null 2>&1); then CONTENT=`grep -i "^${KEYWORD} " ${MBB_CONFIG} | sed -n -e 's/^[^ ]\+ \(.*\)$/\1/p'` echo ${CONTENT} return $ERR_MBB_NOERR else return $ERR_MBB_CFG_NXKEYWORD fi}export -f _mbb_getconfentryfunction _mbb_displayhelpscreen(){ cat <<EOFMyBashBot, version $MBB_VERSIONKnown arguments:--help or -h : this ;-)--configfile or -f FILE : location of the configfile--version or -V : displays versionEOF}export -f _mbb_displayhelpscreenexport MBB_CMDHANDLERS=""function _mbb_registercommandhandler(){ # links a function to recieved text in format !$COMMAND # the function must have the name _mbb_cmdhandler_$COMMAND and must be reachable from within this shell local COMMAND="$1" if [ -z "$MBB_COMMANDHANDLERS" ]; then export MBB_COMMANDHANDLERS=" $COMMAND " else export MBB_COMMANDHANDLERS="${MBB_COMMANDHANDLERS} ${COMMAND} " fi return $MBB_ERR_NOERROR}function _mbb_callcommandhandler(){ local CMD="$1" local CMDARGS="$2" local SOURCE="$3" local TARGET="$4" if [ "$CMD" == "reload" ]; then echo "PRIVMSG ${TARGET} :reloading..." #FUNCLIST=`set | grep "_mbb_commandhandler_[^ ]\+ ()" | sed -n -e 's/^\(_mbb_commandhandler_[^ ]\) .*$/\1/p'` FUNCLIST=`set | grep "^_mbb_commandhandler_[^ ]\+ ()" | sed -n -e 's/^\(_mbb_commandhandler_[^ ]\+\) .*$/\1/p'` for i in $FUNCLIST; do unset -f $i done for i in ${PLUGINSDIR}/*.cmdplugin; do source $i done return $MBB_ERR_NOERROR fi echo "----DEBUG: _mbb_callcommandhandler called with $@" >&7 if !(echo "${MBB_COMMANDHANDLERS}" | grep " ${CMD} " >/dev/null 2>&1); then # CMD not in list of registered plugins return $ERR_MBB_CMDPLGIN_NOPLUGIN else # CMD is in list of registeres plugins _mbb_commandhandler_${CMD} "${SOURCE}" "${TARGET}" "${CMDARGS}" & return $ERR_MBB_NOERROR fi}export -f _mbb_callcommandhandlerfunction _mbb_getnickfromident(){ local IDENT="$1" NICK="`echo "${IDENT}" | sed -n -e 's/\([^!]\)!.*$/\1/p'`" echo "${NICK}"}export -f _mbb_getnickfromidentfunction _mbb_gettargetfromPRIVMSGmessage(){ local MSG="$1" TARGET="`echo "$MSG" | sed -n -e 's/^\([^ ]\+\) .*$/\1/p'`" echo "$TARGET"}function _mbb_getmessagefromPRIVMSGmessage(){ local MSG="$1" MESSAGE="`echo "${MSG}" | sed -n -e 's/^[^ ]\+ :\(.*\)/\1/p'`" echo "${MESSAGE}"}export -f _mbb_gettargetfromPRIVMSGmessage _mbb_getmessagefromPRIVMSGmessage### MAIN ###export MBB_VERSION="0.2"while [ ! -z "$1" ]; docase "$1" in --configfile|-f) export MBB_CONFIG="$2" shift 2 ;; --help|-h) _mbb_displayhelpscreen exit 0 ;; --version|-V) echo "MyBashBot V${MBB_VERSION}" exit 0 ;; *) echo "unknown argument: $1" _mbb_displayhelpscreen exit 1 ;;esacdoneexport BOTNICK=`_mbb_getconfentry BotNick`export BOTUSER=`_mbb_getconfentry BotUser`export BOTRNAME=`_mbb_getconfentry RealName`export BOTSRV=`_mbb_getconfentry Server`export SVRPORT=`_mbb_getconfentry ServerPort`export BOTCHAN=`_mbb_getconfentry Channel`export PLUGINSDIR=`_mbb_getconfentry PluginsDir`export OPLIST=`_mbb_getconfentry Channel`export OWNPID=$$# source the plugins# plugins MUSTS:# be in a file called <COMMAND>.cmdplugin in the $PLUGINSDIR# define and export a function named _mbb_commandhandler_${COMMANDNAME}, where commandname is the string between "^!" and " ", the bot may recieve# call the _mbb_registercommandhandler with the name of the COMMAND to register# e.g. to register the command "op", the function must be named _mbb_commandhandler_op and must be registered with _mbb_registercommandhandler "op"# then it will be called with _mbb_commandhandler_op <sourcenick> <targetnickorchannel> <rest of line># when the string "^!op" appears in a PRIVMSG recieved by the bot.echo DEBUG: ${PLUGINSDIR}for i in ${PLUGINSDIR}/*.cmdplugin; do source $i echo $idone# save FD#0 (stdin) to FD#6 and FD#1 (stdout) to FD#7exec 6<&0exec 7>&1# open the socket, redirect stdin and stdout to that socket (to use old in/out use the filedescriptors above)SOCKET="/dev/tcp/${BOTSRV}/${SVRPORT}"exec >$SOCKETexec <&1# login procedureecho DEBUG: "USER ${BOTUSER} 0 * : ${BOTRNAME}\r\n" >&7echo -en "NICK ${BOTNICK}\r\n"echo -en "USER ${BOTUSER} 0 * : ${BOTRNAME}\r\n"#echo -en "JOIN ${BOTCHAN}\r\n"# sort of main() loop ;)while read SERVERINPUT; do # remove the odd \r's specified in RFC's SERVERINPUT="`echo "$SERVERINPUT" | tr -d '\r'`" #echo "---DEBUG: ${SERVERINPUT}" >&7 if (echo "$SERVERINPUT" | grep "^:" >/dev/null 2>&1); then # normal message ":<from> <command> <params>" : ORIGIN="`echo "$SERVERINPUT" | sed -n -e 's/^:\([^ ]\+\) .*$/\1/p'`" COMMAND="`echo "$SERVERINPUT" | sed -n -e 's/^:[^ ]\+ \([^ ]\+\) .*$/\1/p'`" CMDARGS="`echo "$SERVERINPUT" | sed -n -e 's/^[^ ]\+ [^ ]\+ \(.*\)$/\1/p'`" echo "---DEBUG: ${COMMAND} from ${ORIGIN} is \"${CMDARGS}\"" >&7 # ---DEBUG: PRIVMSG from TheBonsai!~bonsai@pD9E0C2B1.dip.t-dialin.net is "#botchan :!teststring" case "$COMMAND" in [Nn][Oo][Tt][Ii][Cc][Ee]) # NOTICE echo "<NOTICE ${ORIGIN}> ${CMDARGS}" >&7 ;; [Pp][Rr][Ii][Vv][Mm][Ss][Gg]) # PRIVMSG ORIGINNICK="`_mbb_getnickfromident "$ORIGIN"`" MSGTARGET="`_mbb_gettargetfromPRIVMSGmessage "$CMDARGS"`" MSGBODY="`_mbb_getmessagefromPRIVMSGmessage "$CMDARGS"`" echo "<$ORIGINNICK -> $MSGTARGET> $MSGBODY" >&7 if (echo "$MSGBODY" | grep "^\!" >/dev/null 2>&1); then # the MSGBODY is "!......", which is probably a command to the mbb MSGBODY="${MSGBODY} " echo "---MESSAGEBODY is \"${MSGBODY}\"" >&7 BOTCOMMAND=`echo "$MSGBODY" | sed -n -e 's/^\!\([^ ]\+\) .*$/\1/p'` CMDBODY=`echo "$MSGBODY" | sed -n -e 's/^\![^ ]\+ \(.*\)$/\1/p'` echo "---BOT TRIGGERED with \"${BOTCOMMAND}\"" >&7 echo "---where CMDBODY is \"${CMDBODY}\"" >&7 _mbb_callcommandhandler "$BOTCOMMAND" "$CMDBODY" "$ORIGINNICK" "$MSGTARGET" case "$?" in $ERR_MBB_NOERROR) ;; $ERR_MBB_CMDPLGIN_NOPLUGIN) echo -en "PRIVMSG ${MSGTARGET} :from plugin handler: no such plugin (${BOTCOMMAND})\r\n" ;; esac fi if (echo "$MSGBODY" | grep "${BOTNICK}" >/dev/null 2>&1); then echo -en "PRIVMSG ${MSGTARGET} :${ORIGINNICK}, hm?\r\n" fi ;; [Jj][Oo][Ii][Nn]) ORIGINNICK="`_mbb_getnickfromident "$ORIGIN"`" echo -en "PRIVMSG ${MSGTARGET} :Hallo sagen kann jeder... Hallo ${ORIGINNICK} *bleh*\r\n" ;; 37[526]) # RPL_MOTDSTART, RPL_MOTD, RPL_MOTDEND echo "<MOTD> ${CMDARGS}" >&7 ;; 001) # RPL_WELCOME echo "${ORIGIN} welcomes us, joining ${BOTCHAN}" >&7 echo -en "JOIN ${BOTCHAN}\r\n" ;; esac else # message with COMMAND as first argument, message format is now COMMAND [params] (->RFC2812) COMMAND="`echo "$SERVERINPUT" | sed -n -e 's/^\([^ ]\+\) .*$/\1/p'`" CMDARGS="`echo "$SERVERINPUT" | sed -n -e 's/^[^ ]\+ :\(.*\)$/\1/p'`" case "$COMMAND" in [Pp][Ii][Nn][Gg]) echo "PING requested by ${CMDARGS} --> PONG :${CMDARGS}" >&7 echo -en "PONG :${CMDARGS}\r\n" ;; [Ee][Rr][Rr][Oo][Rr]) echo "ERROR sent from server, params: \"${CMDARGS}\"" >&7 ;; *) echo "Currently unknown or misparsed command from server: \"${COMMAND}\" with parameters \"${CMDARGS}\"" >&7 ;; esac fidone