# Connect with: # socat 'TCP:localhost:12345' 'EXEC:awk -f $0' # # Pre-defined variables: # # When connected: # SERVER: IRC Server that is connected to # NICK: Nickname given by the bot # CHANNEL: Channel the bot is currently in # # When a messages is recieved: # CMD: Message, e.g. PRIVMSG # SRC: Source of the message # DST: Destination of the message, e.g. the channel # TO: Nickname the message was addressed to # FROM: Nickname of the user who sent the message # MSG: Message sent # $0: Message sans TO # Debugging function send(msg) { print msg |& socket print " > " msg } function recv(msg) { print msg |& child print " < " msg } function debug(msg) { print " # " msg > "/dev/stderr" } function set() { debug("CMD: " CMD) debug("SRC: " SRC) debug("DST: " DST) debug("FROM: " FROM) debug("TO: " TO) debug("ARG: " ARG) debug("MSG: " MSG) } # Reloading function setup() { "whoami" | getline _name "hostname" | getline _host send("USER " _name " " _host " " server " :" nick) send("NICK " nick) } function connect(server, port, nick, channel) { SERVER = server PORT = port NICK = nick CHANNEL = channel if (CHILD == "") { child = "awk -f rhawk -v CHILD=1 -v FIRST=1" socket = "/inet/tcp/0/" SERVER "/" PORT debug("Starting server"); while (running) { printf "" |& child printf "" |& socket while (connected) { if (!(fd = select("from", child, socket))) { print "timeout" continue } if (!(st = fd |& getline line)) { print "broken pipe" close(fd) break } if (fd == socket) recv(line) if (fd == child) send(line) fflush() } } } else { if (first) setup() debug("Starting child: CHILD=" CHILD " FIRST=" FIRST); } } function quit() { exit(0) } function reload() { exit(1) } # Functions function privmsg(to, msg) { send("PRIVMSG " to " :" msg) } function say(msg) { if (DST ~ "^#") privmsg(DST, msg) else if (DST == NICK && FROM) privmsg(FROM, msg) else privmsg(CHANNEL, msg) } function reply(msg) { say(FROM ": " msg) } function join(chan) { send("JOIN " chan) send("TOPIC " chan) } function part(chan) { send("PART " chan) } function topic(chan, msg) { send("TOPIC " chan " :" msg) } # Input parsing // { match($0, /(:([^ ]+) +)?(([A-Z0-9]+) +)(([^ ]+) +)?(([^: ]+) +)?(:(.*))/, arr); gsub(/\s+/, " ", arr[8]) gsub(/^ | $/, "", arr[8]) gsub(/\3[0-9]*/, "", arr[8]) SRC = arr[2] CMD = arr[4] DST = arr[6] ARG = arr[8] MSG = arr[10] match(SRC, /([^! ]+)!/, arr); FROM = arr[1] match(MSG, /(([^ :,]*)[:,] *)?(.*)/, arr); TO = arr[2] $0 = TO == NICK ? arr[3] : MSG if (CMD == "PRIVMSG" && DST == NICK && FROM) TO = DST } # IRC client CMD == "001" && MSG ~ /Welcome/ { join(CHANNEL) } CMD == "PING" { send("PING " MSG) } CMD == "332" { CMD = "TOPIC" DST = ARG } CMD == "TOPIC" { topics[DST] = MSG }