added user registered event, tidied up helper functions and added automatic auth...
[NeonServV5.git] / src / IRCEvents.c
1 /* IRCEvents.c - NeonServ v5.2
2  * Copyright (C) 2011  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17
18 #include "IRCEvents.h"
19 #include "UserNode.h"
20 #include "ChanNode.h"
21 #include "ChanUser.h"
22 #include "ClientSocket.h"
23 #include "mysqlConn.h"
24
25 struct binding {
26     void *func;
27     struct binding *next;
28 };
29
30 static void **binds;
31 #define BIND_TYPE_JOIN       0
32 #define BIND_TYPE_NICK       1
33 #define BIND_TYPE_PART       2
34 #define BIND_TYPE_QUIT       3
35 #define BIND_TYPE_KICK       4
36 #define BIND_TYPE_TOPIC      5
37 #define BIND_TYPE_MODE       6
38 #define BIND_TYPE_CHANMSG    7
39 #define BIND_TYPE_PRIVMSG    8
40 #define BIND_TYPE_CHANNOTICE 9
41 #define BIND_TYPE_PRIVNOTICE 10
42 #define BIND_TYPE_CHANCTCP   11
43 #define BIND_TYPE_PRIVCTCP   12
44 #define BIND_TYPE_INVITE     13
45 #define BIND_TYPE_RAW        14
46 #define BIND_TYPE_BOT_READY  15
47 #define BIND_TYPE_REGISTERED 16
48
49 #define TOTAL_BIND_TYPES     17
50
51 void init_bind() {
52     binds = calloc(TOTAL_BIND_TYPES, sizeof(*binds));
53 }
54
55 void free_bind() {
56     struct binding *cbind, *next;
57     int i;
58     for(i = 0; i < TOTAL_BIND_TYPES; i++) {
59         for(cbind = binds[i]; cbind; cbind = next) {
60             next = cbind->next;
61             free(cbind);
62         }
63     }
64     free(binds);
65 }
66
67 static int is_bound(unsigned char type, void *func) {
68     struct binding *cbind;
69     for(cbind = binds[type]; cbind; cbind = cbind->next) {
70         if(cbind->func == func) 
71             return 1;
72     }
73     return 0;
74 }
75
76 #define FUNC_BIND(NAME,FUNCTYPE,TYPE) \
77 int bind_##NAME(FUNCTYPE *func) { \
78     if(!is_bound(TYPE, func)) { \
79         struct binding *cbind = malloc(sizeof(*cbind)); \
80         if (!cbind) { \
81             perror("malloc() failed"); \
82             return 0; \
83         } \
84         cbind->func = func; \
85         cbind->next = binds[TYPE]; \
86         binds[TYPE] = cbind; \
87         return 1; \
88     } \
89     return 0; \
90 }
91
92 #define FUNC_UNBIND(NAME,FUNCTYPE,TYPE) \
93 void unbind_##NAME(FUNCTYPE *func) { \
94     struct binding *cbind, *last = NULL, *next; \
95     for(cbind = binds[TYPE]; cbind; cbind = next) { \
96         next = cbind->next; \
97         if(cbind->func == func) { \
98             if(last) \
99                 last->next = cbind->next; \
100             else \
101                 binds[TYPE] = cbind->next; \
102             free(cbind); \
103         } else \
104             last = cbind; \
105     } \
106 }
107
108 #define FUNC_EVENT(NAME,FUNCTYPE,TYPE,PDECLARATION,PLIST) \
109 int event_##NAME PDECLARATION { \
110     struct binding *cbind; \
111     pre_event(TYPE); \
112     for(cbind = binds[TYPE]; cbind; cbind = cbind->next) { \
113         FUNCTYPE *func = cbind->func; \
114         func PLIST; \
115     } \
116     post_event(TYPE); \
117     return 1; \
118 }
119
120 void pre_event(UNUSED_ARG(int type)) {
121
122 }
123
124 void post_event(UNUSED_ARG(int type)) {
125     mysql_free();
126 }
127
128 //EVENTS
129
130 FUNC_BIND(join, join_func_t, BIND_TYPE_JOIN)
131 FUNC_UNBIND(join, join_func_t, BIND_TYPE_JOIN)
132 FUNC_EVENT(join, join_func_t, BIND_TYPE_JOIN, (struct ChanUser *chanuser), (chanuser))
133
134 FUNC_BIND(nick, nick_func_t, BIND_TYPE_NICK)
135 FUNC_UNBIND(nick, nick_func_t, BIND_TYPE_NICK)
136 FUNC_EVENT(nick, nick_func_t, BIND_TYPE_NICK, (struct UserNode *user, char *new_nick), (user, new_nick))
137
138 FUNC_BIND(part, part_func_t, BIND_TYPE_PART)
139 FUNC_UNBIND(part, part_func_t, BIND_TYPE_PART)
140 FUNC_EVENT(part, part_func_t, BIND_TYPE_PART, (struct ChanUser *chanuser, char *reason), (chanuser, reason))
141
142 FUNC_BIND(quit, quit_func_t, BIND_TYPE_QUIT)
143 FUNC_UNBIND(quit, quit_func_t, BIND_TYPE_QUIT)
144 FUNC_EVENT(quit, quit_func_t, BIND_TYPE_QUIT, (struct UserNode *user, char *reason), (user, reason))
145
146 FUNC_BIND(kick, kick_func_t, BIND_TYPE_KICK)
147 FUNC_UNBIND(kick, kick_func_t, BIND_TYPE_KICK)
148 FUNC_EVENT(kick, kick_func_t, BIND_TYPE_KICK, (struct UserNode *user, struct ChanUser *target, char *reason), (user, target, reason))
149
150 FUNC_BIND(topic, topic_func_t, BIND_TYPE_TOPIC)
151 FUNC_UNBIND(topic, topic_func_t, BIND_TYPE_TOPIC)
152 FUNC_EVENT(topic, topic_func_t, BIND_TYPE_TOPIC, (struct UserNode *user, struct ChanNode *chan, const char *new_topic), (user, chan, new_topic))
153
154 FUNC_BIND(mode, mode_func_t, BIND_TYPE_MODE)
155 FUNC_UNBIND(mode, mode_func_t, BIND_TYPE_MODE)
156 FUNC_EVENT(mode, mode_func_t, BIND_TYPE_MODE, (struct UserNode *user, struct ChanNode *chan, char *modes, char **args, int argc), (user, chan, modes, args, argc))
157
158 FUNC_BIND(chanmsg, chanmsg_func_t, BIND_TYPE_CHANMSG)
159 FUNC_UNBIND(chanmsg, chanmsg_func_t, BIND_TYPE_CHANMSG)
160 FUNC_EVENT(chanmsg, chanmsg_func_t, BIND_TYPE_CHANMSG, (struct UserNode *user, struct ChanNode *chan, char *message), (user, chan, message))
161
162 FUNC_BIND(privmsg, privmsg_func_t, BIND_TYPE_PRIVMSG)
163 FUNC_UNBIND(privmsg, privmsg_func_t, BIND_TYPE_PRIVMSG)
164 FUNC_EVENT(privmsg, privmsg_func_t, BIND_TYPE_PRIVMSG, (struct UserNode *user, struct UserNode *target, char *message), (user, target, message))
165
166 FUNC_BIND(channotice, channotice_func_t, BIND_TYPE_CHANNOTICE)
167 FUNC_UNBIND(channotice, channotice_func_t, BIND_TYPE_CHANNOTICE)
168 FUNC_EVENT(channotice, channotice_func_t, BIND_TYPE_CHANNOTICE, (struct UserNode *user, struct ChanNode *chan, char *message), (user, chan, message))
169
170 FUNC_BIND(privnotice, privnotice_func_t, BIND_TYPE_PRIVNOTICE)
171 FUNC_UNBIND(privnotice, privnotice_func_t, BIND_TYPE_PRIVNOTICE)
172 FUNC_EVENT(privnotice, privnotice_func_t, BIND_TYPE_PRIVNOTICE, (struct UserNode *user, struct UserNode *target, char *message), (user, target, message))
173
174 FUNC_BIND(chanctcp, chanctcp_func_t, BIND_TYPE_CHANCTCP)
175 FUNC_UNBIND(chanctcp, chanctcp_func_t, BIND_TYPE_CHANCTCP)
176 FUNC_EVENT(chanctcp, chanctcp_func_t, BIND_TYPE_CHANCTCP, (struct UserNode *user, struct ChanNode *chan, char *command, char *text), (user, chan, command, text))
177
178 FUNC_BIND(privctcp, privctcp_func_t, BIND_TYPE_PRIVCTCP)
179 FUNC_UNBIND(privctcp, privctcp_func_t, BIND_TYPE_PRIVCTCP)
180 FUNC_EVENT(privctcp, privctcp_func_t, BIND_TYPE_PRIVCTCP, (struct UserNode *user, struct UserNode *target, char *command, char *text), (user, target, command, text))
181
182 FUNC_BIND(invite, invite_func_t, BIND_TYPE_INVITE)
183 FUNC_UNBIND(invite, invite_func_t, BIND_TYPE_INVITE)
184 FUNC_EVENT(invite, invite_func_t, BIND_TYPE_INVITE, (struct ClientSocket *client, struct UserNode *user, char *channel), (client, user, channel))
185
186 FUNC_BIND(raw, raw_func_t, BIND_TYPE_RAW)
187 FUNC_UNBIND(raw, raw_func_t, BIND_TYPE_RAW)
188 FUNC_EVENT(raw, raw_func_t, BIND_TYPE_RAW, (struct ClientSocket *client, char *from, char *cmd, char **argv, int argc), (client, from, cmd, argv, argc))
189
190 FUNC_BIND(bot_ready, bot_ready_func_t, BIND_TYPE_BOT_READY)
191 FUNC_UNBIND(bot_ready, bot_ready_func_t, BIND_TYPE_BOT_READY)
192 FUNC_EVENT(bot_ready, bot_ready_func_t, BIND_TYPE_BOT_READY, (struct ClientSocket *client), (client))
193
194 FUNC_BIND(registered, registered_func_t, BIND_TYPE_REGISTERED)
195 FUNC_UNBIND(registered, registered_func_t, BIND_TYPE_REGISTERED)
196 int event_registered(struct UserNode *old_user, struct UserNode *new_user) {
197     struct binding *cbind;
198     int ret = 0;
199     pre_event(BIND_TYPE_REGISTERED);
200     for(cbind = binds[BIND_TYPE_REGISTERED]; cbind; cbind = cbind->next) {
201         registered_func_t *func = cbind->func;
202         ret |= func(old_user, new_user);
203     }
204     post_event(BIND_TYPE_REGISTERED);
205     return ret;
206 }