]> Pileus Git - ~andy/rhawk/blob - irc.awk
save
[~andy/rhawk] / irc.awk
1 # Connect with:
2 #   socat 'TCP:localhost:12345' 'EXEC:awk -f $0'
3 #
4 # Pre-defined variables:
5 #
6 # When connected:
7 #   SERVER:  IRC Server that is connected to
8 #   NICK:    Nickname given by the bot
9 #   CHANNEL: Channel the bot is currently in
10 #
11 # When a messages is recieved:
12 #   CMD:     Message, e.g. PRIVMSG
13 #   SRC:     Source of the message
14 #   DST:     Destination of the message, e.g. the channel
15 #   TO:      Nickname the message was addressed to
16 #   FROM:    Nickname of the user who sent the message
17 #   MSG:     Message sent
18 #   $0:      Message sans TO
19
20 # Debugging
21 function send(msg) {
22         #print "  > " msg > "/dev/stderr"
23         print msg
24         #system("sleep 1")
25         fflush()
26 }
27
28 // {
29         #print ""         > "/dev/stderr"
30         #print "  < " $0  > "/dev/stderr"
31 }
32
33 function debug(msg) {
34         print "  # " msg > "/dev/stderr"
35         fflush()
36 }
37
38 function set() {
39         debug("CMD:  " CMD)
40         debug("SRC:  " SRC)
41         debug("DST:  " DST)
42         debug("FROM: " FROM)
43         debug("TO:   " TO)
44         debug("MSG:  " MSG)
45 }
46
47 # Functions
48 function connect(server, nick, channel) {
49         SERVER  = server
50         NICK    = nick
51         CHANNEL = channel
52         if (FIRST) {
53                 "whoami"   | getline _name
54                 "hostname" | getline _host
55                 send("USER " _name " " _host " " server " :" nick)
56                 send("NICK " nick)
57         }
58 }
59 function privmsg(to, msg) {
60         send("PRIVMSG " to " :" msg)
61 }
62 function say(msg) {
63         if (DST ~ "^#")
64                 privmsg(DST, msg)
65         else if (DST == NICK && FROM)
66                 privmsg(FROM, msg)
67         else
68                 privmsg(CHANNEL, msg)
69 }
70
71 function reply(msg) {
72         say(FROM ": " msg)
73 }
74
75 function join(chan) {
76         send("JOIN " chan)
77 }
78
79 function part(chan) {
80         send("PART " chan)
81 }
82
83 # Reloading
84 BEGIN {
85         if (CHILD == "") {
86                 debug("Starting server");
87                 status = system("awk -f rhawk -v CHILD=1 -v FIRST=1");
88                 while (status)
89                         status = system("awk -f rhawk -v CHILD=1");
90                 exit(0);
91         } else {
92                 debug("Starting child: CHILD=" CHILD " FIRST=" FIRST);
93         }
94 }
95
96 function quit() {
97         exit(0)
98 }
99
100 function reload() {
101         exit(1)
102 }
103
104 # Input parsing
105 // {
106         match($0, /(:([^ ]+) +)?(([A-Z0-9]+) +)(([^ ]+) +)?([^:]*:(.*))/, arr);
107         gsub(/\s+/,     " ", arr[8])
108         gsub(/^ | $/,    "", arr[8])
109         gsub(/\3[0-9]*/, "", arr[8])
110         SRC = arr[2]
111         CMD = arr[4]
112         DST = arr[6]
113         MSG = arr[8]
114
115         match(SRC, /([^! ]+)!/, arr);
116         FROM = arr[1]
117
118         match(MSG, /(([^ :,]*)[:,] *)?(.*)/, arr);
119         TO  = arr[2]
120         $0  = TO == NICK ? arr[3] : MSG
121
122         if (CMD == "PRIVMSG" && DST == NICK && FROM)
123                 TO = DST
124 }
125
126 # IRC client
127 CMD == "001" && MSG ~ /Welcome/ {
128         join(CHANNEL)
129 }
130
131 CMD == "PING" {
132         send("PING " MSG)
133 }