#!/bin/bash # bashy # IRC bot written using bash, bash sockets and CLI tools # Jan Schampera ### CONFIG BSHY_IRCSRV="irc.freenode.net" BSHY_IRCPORT="6667" BSHY_IRCCHAN="#bash" BSHY_IRCUSER="bashy" BSHY_IRCNAME="Bashy" BSHY_IRCNICK="bashy" BSHY_IRCMASTER="TheBonsai" BSHY_PLUGINSDIR="/home/bonsai/devel/irc-bots/Bashy/plugins" BSHY_PLUGINSENABLE="y" BSHY_TRIGGERCHAR=";" ### /CONFIG ### NO CHANGES SHOULD BE NECCESARY BEYOND THIS POINT ### ### IF YOU NEED TO CHANGE SOMETHING YOU THINK IT MUST BE CONFIGURABLE, EMAIL ME ### ### INTERNALS export BSHY_VERSION="0.1" ### /INTERNALS ### FUNCTIONS bshy_helpscreen() { cat <&2 # levels: # 0 - always # 1 - general debug info # 2 - detailed debug info } bshy_consoleinput() { while :; do read -r CONSOLEINPUT; case "${CONSOLEINPUT}" in /*) echo "${CONSOLEINPUT:1}" >&6 CONSOLEINPUT="" ;; *) echo "PRIVMSG ${BSHY_IRCCHAN} :${CONSOLEINPUT}" >&6 CONSOLEINPUT="" ;; esac done } export -f bshy_helpscreen bshy_debugmsg bshy_consoleinput ### /FUNCTIONS ### MAIN # begin PARSE_CMDLINE # interpret my commandline arguments while [ ! -z "${1}" ]; do case "${1}" in "--configfile"|"-f") BSHY_CONFIG="${2}" shift 2 ;; "--help"|"-h") bshy_helpscreen exit 0 ;; "--version"|"-v") echo "${BSHY_VERSION}" exit 0 ;; *) echo "Eh?" >&2 bshy_helpscreen >&2 exit 1 ;; esac done # end PARSE_CMDLINE # begin READ_PLUGINS if [ "${BSHY_PLUGINSDIR}" = "y" ]; then bshy_debugmsg 1 READ_PLUGINS "processing plugins in ${BSHY_PLUGINSDIR}" [ -d "${BSHY_PLUGINSENABLE}" ] || { bshy_debugmsg 0 READ_PLUGINS "${BSHY_PLUGINSDIR} not found"; exit 1; } for APLUGIN in ${BSHY_PLUGINSDIR}; do bshy_debugmsg 2 READ_PLUGINS "processing plugin ${APLUGIN}" source "${APLUGIN}" done fi # end READ_PLUGINS # begin CREATE_SOCKET # create the socket (FD 5 in and 6 out) export BSHY_SOCKET="/dev/tcp/${BSHY_IRCSRV}/${BSHY_IRCPORT}" bshy_debugmsg 1 CREATE_SOCKET "creating socket" bshy_debugmsg 2 CREATE_SOCKET "attempting to create socket in ${BSHY_SOCKET}" exec 6>${BSHY_SOCKET} exec 5<&6 # end CREATE_SOCKET # begin LOGIN echo -en "NICK ${BSHY_IRCNICK}\r\n" >&6 echo -en "USER ${BSHY_IRCUSER} 0 * : ${BSHY_IRCNAME}\r\n" >&6 # end LOGIN # start console input background process bshy_consoleinput <&0 & CONSINPTPID="$!" # begin MAIN_LOOP #set -x while read SERVERINPUT <&5; do # remove the off \r's specified in RFC SERVERINPUT="${SERVERINPUT//$'\r'/}" # is it a normal server message ':ORIGIN MESSAGETYPE MESSAGE'? [ "${SERVERINPUT:0:1}" = ":" ] && IS_A_MESSAGE=1 || IS_A_MESSAGE=0 # if it's a normal message, remove the leading ':' [ "${IS_A_MESSAGE}" = "1" ] && SERVERINPUT="${SERVERINPUT:1}" case "${IS_A_MESSAGE}" in "1") # parse the message line, ':' was removed before SRVMSG_ORIGIN="${SERVERINPUT%% *}" SRVMSG_COMMAND="${SERVERINPUT%% :*}"; SRVMSG_COMMAND="${SRVMSG_COMMAND#* }" SRVMSG_TYPE="${SRVMSG_COMMAND%% *}" SRVMSG_TARGET="${SRVMSG_COMMAND#* }" # SRVMSG_TYPE="${SERVERINPUT#* }"; SRVMSG_TYPE="${SERVERINPUT%% *}" SRVMSG_MESSAGE="${SERVERINPUT#* :}" case "${SRVMSG_TYPE}" in 37[256]) # RPL_MOTD, RPL_MOTDSTART, RPL_MOTDEND echo " ${SRVMSG_MESSAGE}" ;; 001) # RPL_WELCOME echo " ${SRVMSG_ORIGIN} wecomes us, joining ${BSHY_IRCCHAN}" echo -en "JOIN ${BSHY_IRCCHAN}\r\n" >&6 ;; 00[2345]) : # ignored: RPL_YOURHOST, RPL_CREATED, RPL_MYINFO, RPL_BOUNCE ;; 25?) : # ignored: server informational messages ;; "353"|"366") : # ignored: RPL_NAMREPLY, RPL_ENDOFNAMES ;; 33[123]) : # ignored: RPL_NOTOPIC, RPL_TOPIC, and 333 as in "set by X at " ;; [Jj][Oo][Ii][Nn]) echo " ${SRVMSG_ORIGIN%%!*} has joined ${SRVMSG_MESSAGE}" ;; [Pp][Aa][Rr][Tt]) echo " ${SRVMSG_ORIGIN%%!*} has left ${SRVMSG_TARGET} (${SRVMSG_MESSAGE})" ;; [Qq][Uu][Ii][Tt]) echo " ${SRVMSG_ORIGIN%%!*} has quit (${SRVMSG_MESSAGE})" ;; [Pp][Rr][Ii][Vv][Mm][Ss][Gg]) echo "${SRVMSG_TARGET}> ${SRVMSG_MESSAGE}" if [ "${SRVMSG_MESSAGE:0:1}" = "${BSHY_TRIGGERCHAR:0:1}" ]; then echo " triggered by ${SRVMSG_ORIGIN%%!*} in ${SRVMSG_TARGET}" fi ;; [Mm][Oo][Dd][Ee]) echo " ${SRVMSG_ORIGIN%%!*} sets mode ${SRVMSG_MESSAGE} for ${SRVMSG_TARGET}" ;; *) echo " COMPLETE LINE WAS: ${SERVERINPUT}" ;; esac ;; "0") SRVMSG_TYPE="${SERVERINPUT%% *}" SRVMSG_TARGET="${SERVERINPUT#* }"; SRVMSG_TARGET="${SRVMSG_TARGET%% :*}" SRVMSG_MESSAGE="${SERVERINPUT##*:}" case "${SRVMSG_TYPE}" in [Nn][Oo][Tt][Ii][Cc][Ee]) echo " ${SRVMSG_MESSAGE}" ;; [Pp][Ii][Nn][Gg]) echo " PONG!" echo -en "PONG :${SRVMSG_MESSAGE}\r\n" >&6 ;; [Ee][Rr][Rr][Oo][Rr]) echo " ${SRVMSG_MESSAGE}" ;; esac ;; esac done # end MAIN_LOOP ### /MAIN