1 | /* |
1 | /* |
2 | * phandler.C: Generic protocol handling routines. |
2 | * phandler.C: Generic protocol handling routines. |
3 | * Rights to this code are documented in doc/pod/license.pod. |
3 | * Rights to this code are documented in doc/pod/license.pod. |
4 | * |
4 | * |
5 | * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) |
5 | * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) |
6 | */ |
6 | */ |
7 | |
7 | |
8 | static char const rcsid[] = "$Id: phandler.C,v 1.3 2007/07/21 13:23:22 pippijn Exp $"; |
8 | static char const rcsid[] = "$Id: phandler.C,v 1.4 2007/08/28 17:08:12 pippijn Exp $"; |
9 | |
9 | |
10 | #include "atheme.h" |
10 | #include "atheme.h" |
11 | #include <account/chanacs.h> |
11 | #include <account/chanacs.h> |
12 | #include "uplink.h" |
12 | #include "uplink.h" |
13 | |
13 | |
14 | unsigned int |
14 | namespace protocol |
15 | generic_server_login (void) |
|
|
16 | { |
15 | { |
|
|
16 | unsigned int |
|
|
17 | handler::server_login (void) |
|
|
18 | { |
17 | /* Nothing to do here. */ |
19 | /* Nothing to do here. */ |
18 | return 0; |
20 | return 0; |
19 | } |
21 | } |
20 | |
22 | |
21 | static void |
23 | void |
22 | generic_introduce_nick (user_t *u) |
24 | handler::introduce_nick (user_t *u) |
23 | { |
25 | { |
24 | /* Nothing to do here. */ |
26 | /* Nothing to do here. */ |
25 | } |
27 | } |
26 | |
28 | |
27 | static void |
29 | void |
28 | generic_wallops_sts (const char *text) |
30 | handler::wallops_sts (char const * const text) |
29 | { |
31 | { |
30 | slog (LG_INFO, "Don't know how to send wallops: %s", text); |
32 | slog (LG_INFO, "Don't know how to send wallops: %s", text); |
31 | } |
33 | } |
32 | |
34 | |
33 | static void |
35 | void |
34 | generic_join_sts (channel_t *c, user_t *u, bool isnew, char *modes) |
36 | handler::join_sts (channel_t *c, user_t *u, bool isnew, char const * const modes) |
35 | { |
37 | { |
36 | /* We can't do anything here. Bail. */ |
38 | /* We can't do anything here. Bail. */ |
37 | } |
39 | } |
38 | |
40 | |
39 | static void |
41 | void |
40 | generic_chan_lowerts (channel_t *c, user_t *u) |
42 | handler::chan_lowerts (channel_t *c, user_t *u) |
41 | { |
43 | { |
42 | slog (LG_ERROR, "chan_lowerts() called but not supported!"); |
44 | slog (LG_ERROR, "chan_lowerts() called but not supported!"); |
43 | join_sts (c, u, true, channel_modes (c, true)); |
45 | join_sts (c, u, true, channel_modes (c, true)); |
44 | } |
46 | } |
45 | |
47 | |
46 | static void |
48 | void |
47 | generic_kick (char *from, char *channel, char *to, char *reason) |
49 | handler::kick (char const * const from, char const * const channel, char const * const to, char const * const reason) |
48 | { |
50 | { |
49 | /* We can't do anything here. Bail. */ |
51 | /* We can't do anything here. Bail. */ |
50 | } |
52 | } |
51 | |
53 | |
52 | static void |
54 | void |
53 | generic_mdchange (char const *target, char const *key, char const *value) |
55 | handler::mdchange (char const *target, char const *key, char const *value) |
54 | { |
56 | { |
55 | /* We can't do anything here. Bail. */ |
57 | /* We can't do anything here. Bail. */ |
56 | } |
58 | } |
57 | |
59 | |
58 | static void |
60 | void |
59 | generic_msg (const char *from, const char *target, const char *fmt, ...) |
61 | handler::privmsg (char const * const from, char const * const target, char const * const fmt, ...) |
60 | { |
62 | { |
61 | va_list ap; |
63 | va_list ap; |
62 | char *buf; |
64 | char *buf; |
63 | |
65 | |
64 | va_start (ap, fmt); |
66 | va_start (ap, fmt); |
65 | vasprintf (&buf, fmt, ap); |
67 | vasprintf (&buf, fmt, ap); |
66 | va_end (ap); |
68 | va_end (ap); |
67 | |
69 | |
68 | slog (LG_INFO, "Cannot send message to %s (%s): don't know how. Load a protocol module perhaps?", target, buf); |
70 | slog (LG_INFO, "Cannot send message to %s (%s): don't know how. Load a protocol module perhaps?", target, buf); |
69 | free (buf); |
71 | sfree (buf); |
70 | } |
72 | } |
71 | |
73 | |
72 | static void |
74 | void |
73 | generic_notice_user_sts (user_t *from, user_t *target, const char *text) |
75 | handler::notice_user_sts (user_t *from, user_t *target, char const * const text) |
74 | { |
76 | { |
75 | slog (LG_INFO, "Cannot send notice to %s (%s): don't know how. Load a protocol module perhaps?", target->nick, text); |
77 | slog (LG_INFO, "Cannot send notice to %s (%s): don't know how. Load a protocol module perhaps?", target->nick, text); |
76 | } |
78 | } |
77 | |
79 | |
78 | static void |
80 | void |
79 | generic_notice_global_sts (user_t *from, const char *mask, const char *text) |
81 | handler::notice_global_sts (user_t *from, char const * const mask, char const * const text) |
80 | { |
82 | { |
81 | slog (LG_INFO, "Cannot send global notice to %s (%s): don't know how. Load a protocol module perhaps?", mask, text); |
83 | slog (LG_INFO, "Cannot send global notice to %s (%s): don't know how. Load a protocol module perhaps?", mask, text); |
82 | } |
84 | } |
83 | |
85 | |
84 | static void |
86 | void |
85 | generic_notice_channel_sts (user_t *from, channel_t *target, const char *text) |
87 | handler::notice_channel_sts (user_t *from, channel_t *target, char const * const text) |
86 | { |
88 | { |
87 | slog (LG_INFO, "Cannot send notice to %s (%s): don't know how. Load a protocol module perhaps?", target->name, text); |
89 | slog (LG_INFO, "Cannot send notice to %s (%s): don't know how. Load a protocol module perhaps?", target->name, text); |
88 | } |
90 | } |
89 | |
91 | |
90 | extern void // XXX: extern |
92 | void |
91 | generic_wallchops (user_t *sender, channel_t *channel, const char *message) |
93 | handler::wallchops (user_t *sender, channel_t *channel, char const * const message) |
92 | { |
94 | { |
93 | /* ugly, but always works -- jilles */ |
95 | /* ugly, but always works -- jilles */ |
94 | node_t *n; |
96 | node_t *n; |
95 | chanuser_t *cu; |
97 | chanuser_t *cu; |
96 | |
98 | |
97 | LIST_FOREACH (n, channel->members.head) |
99 | LIST_FOREACH (n, channel->members.head) |
98 | { |
100 | { |
99 | cu = (chanuser_t *) n->data; |
101 | cu = (chanuser_t *) n->data; |
100 | if (cu->user->server != me.me && cu->modes & CMODE_OP) |
102 | if (cu->user->server != me.me && cu->modes & CMODE_OP) |
101 | notice (sender->nick, cu->user->nick, "[@%s] %s", channel->name, message); |
103 | notice (sender->nick, cu->user->nick, "[@%s] %s", channel->name, message); |
|
|
104 | } |
|
|
105 | } |
102 | } |
106 | |
103 | } |
107 | void |
104 | |
108 | handler::numeric_sts (char const * const from, int numeric, char const * const target, char const * const fmt, ...) |
105 | static void |
109 | { |
106 | generic_numeric_sts (char *from, int numeric, char *target, char *fmt, ...) |
|
|
107 | { |
|
|
108 | va_list va; |
110 | va_list va; |
109 | char *buf; |
111 | char *buf; |
110 | |
112 | |
111 | va_start (va, fmt); |
113 | va_start (va, fmt); |
112 | vasprintf (&buf, fmt, va); |
114 | vasprintf (&buf, fmt, va); |
113 | va_end (va); |
115 | va_end (va); |
114 | |
116 | |
115 | sts (":%s %d %s %s", from, numeric, target, buf); |
117 | sts (":%s %d %s %s", from, numeric, target, buf); |
116 | free (buf); |
118 | sfree (buf); |
117 | } |
119 | } |
118 | |
120 | |
119 | static void |
121 | void |
120 | generic_skill (char *from, char *nick, char *fmt, ...) |
122 | handler::skill (char const * const from, char const * const nick, char const * const fmt, ...) |
121 | { |
123 | { |
122 | /* cant do anything here. bail. */ |
124 | /* cant do anything here. bail. */ |
123 | } |
125 | } |
124 | |
126 | |
125 | static void |
127 | void |
126 | generic_part_sts (channel_t *c, user_t *u) |
128 | handler::part_sts (channel_t *c, user_t *u) |
127 | { |
129 | { |
128 | /* cant do anything here. bail. */ |
130 | /* cant do anything here. bail. */ |
129 | } |
131 | } |
130 | |
132 | |
131 | static void |
133 | void |
132 | generic_kline_sts (char *server, char *user, char *host, long duration, char *reason) |
134 | handler::kline_sts (char const * const server, char const * const user, char const * const host, long duration, char const * const reason) |
133 | { |
135 | { |
134 | /* cant do anything here. bail. */ |
136 | /* cant do anything here. bail. */ |
135 | } |
137 | } |
136 | |
138 | |
137 | static void |
139 | void |
138 | generic_unkline_sts (char *server, char *user, char *host) |
140 | handler::unkline_sts (char const * const server, char const * const user, char const * const host) |
139 | { |
141 | { |
140 | /* cant do anything here. bail. */ |
142 | /* cant do anything here. bail. */ |
141 | } |
143 | } |
142 | |
144 | |
143 | static void |
145 | void |
144 | generic_topic_sts (channel_t *c, const char *setter, time_t ts, time_t prevts, const char *topic) |
146 | handler::topic_sts (channel_t *c, char const * const setter, time_t ts, time_t prevts, char const * const topic) |
145 | { |
147 | { |
146 | /* cant do anything here. bail. */ |
148 | /* cant do anything here. bail. */ |
147 | } |
149 | } |
148 | |
150 | |
149 | static void |
151 | void |
150 | generic_mode_sts (char *sender, channel_t *target, char *modes) |
152 | handler::mode_sts (char const * const sender, channel_t *target, char const * const modes) |
151 | { |
153 | { |
152 | /* cant do anything here. bail. */ |
154 | /* cant do anything here. bail. */ |
153 | } |
155 | } |
154 | |
156 | |
155 | static void |
157 | void |
156 | generic_ping_sts (void) |
158 | handler::ping_sts (void) |
157 | { |
159 | { |
158 | /* cant do anything here. bail. */ |
160 | /* cant do anything here. bail. */ |
159 | } |
161 | } |
160 | |
162 | |
161 | static void |
163 | void |
162 | generic_quit_sts (user_t *u, const char *reason) |
164 | handler::quit_sts (user_t *u, char const * const reason) |
163 | { |
165 | { |
164 | /* cant do anything here. bail. */ |
166 | /* cant do anything here. bail. */ |
165 | } |
167 | } |
166 | |
168 | |
167 | static void |
169 | void |
168 | generic_on_login (char *origin, char *user, char *wantedhost) |
170 | handler::ircd_on_login (char const * const origin, char const * const user, char const * const wantedhost) |
169 | { |
171 | { |
170 | /* nothing to do here. */ |
172 | /* nothing to do here. */ |
171 | } |
173 | } |
172 | |
174 | |
173 | bool |
175 | bool |
174 | generic_on_logout (char *origin, char *user, char *wantedhost) |
176 | handler::ircd_on_logout (char const * const origin, char const * const user, char const * const wantedhost) |
175 | { |
177 | { |
176 | /* nothing to do here. */ |
178 | /* nothing to do here. */ |
177 | return false; |
179 | return false; |
178 | } |
180 | } |
179 | |
181 | |
180 | static void |
182 | void |
181 | generic_jupe (const char *server, const char *reason) |
183 | handler::jupe (char const * const server, char const * const reason) |
182 | { |
184 | { |
183 | /* nothing to do here. */ |
185 | /* nothing to do here. */ |
184 | } |
186 | } |
185 | |
187 | |
186 | static void |
188 | void |
187 | generic_sethost_sts (char *source, char *target, char *host) |
189 | handler::sethost_sts (char const * const source, char const * const target, char const * const host) |
188 | { |
190 | { |
189 | /* nothing to do here. */ |
191 | /* nothing to do here. */ |
190 | } |
192 | } |
191 | |
193 | |
192 | extern void // XXX extern? |
194 | void |
193 | generic_fnc_sts (user_t *source, user_t *u, char *newnick, int type) |
195 | handler::fnc_sts (user_t *source, user_t *u, char const * const newnick, int type) |
194 | { |
196 | { |
195 | if (type == FNC_FORCE) |
197 | if (type == FNC_FORCE) |
196 | skill (source->nick, u->nick, "Nickname enforcement (%s)", u->nick); |
198 | skill (source->nick, u->nick, "Nickname enforcement (%s)", u->nick); |
197 | } |
199 | } |
198 | |
200 | |
199 | static void |
201 | void |
200 | generic_holdnick_sts (user_t *source, int duration, const char *nick, myuser_t *account) |
202 | handler::holdnick_sts (user_t *source, int duration, char const * const nick, myuser_t *account) |
201 | { |
203 | { |
202 | /* nothing to do here. */ |
204 | /* nothing to do here. */ |
203 | } |
205 | } |
204 | |
206 | |
205 | static void |
207 | void |
206 | generic_invite_sts (user_t *source, user_t *target, channel_t *channel) |
208 | handler::invite_sts (user_t *source, user_t *target, channel_t *channel) |
207 | { |
209 | { |
208 | /* nothing to do here. */ |
210 | /* nothing to do here. */ |
209 | } |
211 | } |
210 | |
212 | |
211 | static void |
213 | void |
212 | generic_svslogin_sts (char *target, char *nick, char *user, char *host, char *login) |
214 | handler::svslogin_sts (char const * const target, char const * const nick, char const * const user, char const * const host, char const * const login) |
213 | { |
215 | { |
214 | /* nothing to do here. */ |
216 | /* nothing to do here. */ |
215 | } |
217 | } |
216 | |
218 | |
217 | static void |
219 | void |
218 | generic_sasl_sts (char *target, char mode, char *data) |
220 | handler::sasl_sts (char const * const target, char const mode, char const * const data) |
219 | { |
221 | { |
220 | /* nothing to do here. */ |
222 | /* nothing to do here. */ |
221 | } |
223 | } |
222 | |
224 | |
223 | static node_t * |
225 | node_t * |
224 | generic_next_matching_ban (channel_t *c, user_t *u, int type, node_t *first) |
226 | handler::next_matching_ban (channel_t *c, user_t *u, int type, node_t *first) |
225 | { |
227 | { |
226 | chanban_t *cb; |
228 | chanban_t *cb; |
227 | node_t *n; |
229 | node_t *n; |
228 | char hostbuf[NICKLEN + USERLEN + HOSTLEN]; |
230 | char hostbuf[NICKLEN + USERLEN + HOSTLEN]; |
229 | char realbuf[NICKLEN + USERLEN + HOSTLEN]; |
231 | char realbuf[NICKLEN + USERLEN + HOSTLEN]; |
230 | char ipbuf[NICKLEN + USERLEN + HOSTLEN]; |
232 | char ipbuf[NICKLEN + USERLEN + HOSTLEN]; |
231 | |
233 | |
232 | snprintf (hostbuf, sizeof hostbuf, "%s!%s@%s", u->nick, u->user, u->vhost); |
234 | snprintf (hostbuf, sizeof hostbuf, "%s!%s@%s", u->nick, u->user, u->vhost); |
233 | snprintf (realbuf, sizeof realbuf, "%s!%s@%s", u->nick, u->user, u->host); |
235 | snprintf (realbuf, sizeof realbuf, "%s!%s@%s", u->nick, u->user, u->host); |
234 | /* will be nick!user@ if ip unknown, doesn't matter */ |
236 | /* will be nick!user@ if ip unknown, doesn't matter */ |
235 | snprintf (ipbuf, sizeof ipbuf, "%s!%s@%s", u->nick, u->user, u->ip); |
237 | snprintf (ipbuf, sizeof ipbuf, "%s!%s@%s", u->nick, u->user, u->ip); |
236 | LIST_FOREACH (n, first) |
238 | LIST_FOREACH (n, first) |
237 | { |
239 | { |
238 | cb = static_cast<chanban_t *> (n->data); |
240 | cb = static_cast<chanban_t *> (n->data); |
239 | |
241 | |
240 | if (cb->type == type && (!match (cb->mask, hostbuf) || !match (cb->mask, realbuf) || !match (cb->mask, ipbuf) || (ircd->flags & IRCD_CIDR_BANS && !match_cidr (cb->mask, ipbuf)))) |
242 | if (cb->type == type && (!match (cb->mask, hostbuf) || !match (cb->mask, realbuf) || !match (cb->mask, ipbuf) || (ircd->flags & IRCD_CIDR_BANS && !match_cidr (cb->mask, ipbuf)))) |
241 | return n; |
243 | return n; |
242 | } |
244 | } |
243 | return NULL; |
245 | return NULL; |
244 | } |
246 | } |
245 | |
247 | |
246 | static node_t * |
248 | node_t * |
247 | generic_next_matching_host_chanacs (mychan_t *mc, user_t *u, node_t *first) |
249 | handler::next_matching_host_chanacs (mychan_t *mc, user_t *u, node_t *first) |
248 | { |
250 | { |
249 | chanacs_t *ca; |
251 | chanacs_t *ca; |
250 | node_t *n; |
252 | node_t *n; |
251 | char hostbuf[NICKLEN + USERLEN + HOSTLEN]; |
253 | char hostbuf[NICKLEN + USERLEN + HOSTLEN]; |
252 | char ipbuf[NICKLEN + USERLEN + HOSTLEN]; |
254 | char ipbuf[NICKLEN + USERLEN + HOSTLEN]; |
253 | |
255 | |
254 | snprintf (hostbuf, sizeof hostbuf, "%s!%s@%s", u->nick, u->user, u->vhost); |
256 | snprintf (hostbuf, sizeof hostbuf, "%s!%s@%s", u->nick, u->user, u->vhost); |
255 | /* will be nick!user@ if ip unknown, doesn't matter */ |
257 | /* will be nick!user@ if ip unknown, doesn't matter */ |
256 | snprintf (ipbuf, sizeof ipbuf, "%s!%s@%s", u->nick, u->user, u->ip); |
258 | snprintf (ipbuf, sizeof ipbuf, "%s!%s@%s", u->nick, u->user, u->ip); |
257 | |
259 | |
258 | LIST_FOREACH (n, first) |
260 | LIST_FOREACH (n, first) |
259 | { |
261 | { |
260 | ca = static_cast<chanacs_t *> (n->data); |
262 | ca = static_cast<chanacs_t *> (n->data); |
261 | |
263 | |
262 | if (ca->myuser != NULL) |
264 | if (ca->myuser != NULL) |
263 | continue; |
265 | continue; |
264 | if (!match (ca->host, hostbuf) || !match (ca->host, ipbuf) || (ircd->flags & IRCD_CIDR_BANS && !match_cidr (ca->host, ipbuf))) |
266 | if (!match (ca->host, hostbuf) || !match (ca->host, ipbuf) || (ircd->flags & IRCD_CIDR_BANS && !match_cidr (ca->host, ipbuf))) |
265 | return n; |
267 | return n; |
266 | } |
268 | } |
267 | return NULL; |
269 | return NULL; |
268 | } |
270 | } |
269 | |
271 | } // namespace protocol |
270 | unsigned int (*server_login) (void) = generic_server_login; |
|
|
271 | void (*introduce_nick) (user_t *u) = generic_introduce_nick; |
|
|
272 | void (*wallops_sts) (const char *text) = generic_wallops_sts; |
|
|
273 | void (*join_sts) (channel_t *c, user_t *u, bool isnew, char *modes) = generic_join_sts; |
|
|
274 | void (*chan_lowerts) (channel_t *c, user_t *u) = generic_chan_lowerts; |
|
|
275 | void (*kick) (char *from, char *channel, char *to, char *reason) = generic_kick; |
|
|
276 | void (*mdchange) (const char *target, const char *key, const char *value) = generic_mdchange; |
|
|
277 | void (*msg) (const char *from, const char *target, const char *fmt, ...) = generic_msg; |
|
|
278 | void (*notice_user_sts) (user_t *from, user_t *target, const char *text) = generic_notice_user_sts; |
|
|
279 | void (*notice_global_sts) (user_t *from, const char *mask, const char *text) = generic_notice_global_sts; |
|
|
280 | void (*notice_channel_sts) (user_t *from, channel_t *target, const char *text) = generic_notice_channel_sts; |
|
|
281 | void (*wallchops) (user_t *source, channel_t *target, const char *message) = generic_wallchops; |
|
|
282 | void (*numeric_sts) (char *from, int numeric, char *target, char *fmt, ...) = generic_numeric_sts; |
|
|
283 | void (*skill) (char *from, char *nick, char *fmt, ...) = generic_skill; |
|
|
284 | void (*part_sts) (channel_t *c, user_t *u) = generic_part_sts; |
|
|
285 | void (*kline_sts) (char *server, char *user, char *host, long duration, char *reason) = generic_kline_sts; |
|
|
286 | void (*unkline_sts) (char *server, char *user, char *host) = generic_unkline_sts; |
|
|
287 | void (*topic_sts) (channel_t *c, const char *setter, time_t ts, time_t prevts, const char *topic) = generic_topic_sts; |
|
|
288 | void (*mode_sts) (char *sender, channel_t *target, char *modes) = generic_mode_sts; |
|
|
289 | void (*ping_sts) (void) = generic_ping_sts; |
|
|
290 | void (*quit_sts) (user_t *u, const char *reason) = generic_quit_sts; |
|
|
291 | void (*ircd_on_login) (char *origin, char *user, char *wantedhost) = generic_on_login; |
|
|
292 | bool (*ircd_on_logout) (char *origin, char *user, char *wantedhost) = generic_on_logout; |
|
|
293 | void (*jupe) (const char *server, const char *reason) = generic_jupe; |
|
|
294 | void (*sethost_sts) (char *source, char *target, char *host) = generic_sethost_sts; |
|
|
295 | void (*fnc_sts) (user_t *source, user_t *u, char *newnick, int type) = generic_fnc_sts; |
|
|
296 | void (*holdnick_sts) (user_t *source, int duration, const char *nick, myuser_t *account) = generic_holdnick_sts; |
|
|
297 | void (*invite_sts) (user_t *source, user_t *target, channel_t *channel) = generic_invite_sts; |
|
|
298 | void (*svslogin_sts) (char *target, char *nick, char *user, char *host, char *login) = generic_svslogin_sts; |
|
|
299 | void (*sasl_sts) (char *target, char mode, char *data) = generic_sasl_sts; |
|
|
300 | node_t *(*next_matching_ban) (channel_t *c, user_t *u, int type, node_t *first) = generic_next_matching_ban; |
|
|
301 | node_t *(*next_matching_host_chanacs) (mychan_t *mc, user_t *u, node_t *first) = generic_next_matching_host_chanacs; |
|
|