]>
Commit | Line | Data |
---|---|---|
1 | attempt to move checks for chanmodes c C N T u into | |
2 | the *_can_send_to_channel() functions in channel.c where ircu by default has its chanmode checks | |
3 | ||
4 | instead of having them in each of the places used (m_wallchops, m_wallvoices, ircd_relay.c, etc.) | |
5 | not tested completely | |
6 | ||
7 | client_can_send_to_channel() | |
8 | and | |
9 | member_can_send_to_channel() | |
10 | ||
11 | move our cCNT mode checks to new function can_send_to_channel() used | |
12 | from the two functions above | |
13 | now the checks for cCNT modes are in one place. | |
14 | check for +u remains in member_can_send_to_chan() - as quit from non-member does not show | |
15 | ||
16 | need to verify handling of remote users, services, servers etc. | |
17 | ||
18 | possible problem discovered (ircu): | |
19 | in some places *_can_send_to_channel() is first called with reveal delayedjoin user ON | |
20 | but the code then proceeds to check target limits, which upon refusal means the delayedjoin | |
21 | user is revealed (locally) without actually sending anything to the channel... | |
22 | ...that seems wrong/weird | |
23 | ||
24 | diff -r 7113a0179d71 include/channel.h | |
25 | --- a/include/channel.h Wed Jan 21 16:44:50 2009 +0100 | |
26 | +++ b/include/channel.h Wed Jan 21 17:13:44 2009 +0100 | |
27 | @@ -103,9 +103,9 @@ | |
28 | #define MODE_DELJOINS 0x1000 /**< New join messages are delayed */ | |
29 | #define MODE_REGISTERED 0x2000 /**< Channel marked as registered | |
30 | * (for future semantic expansion) */ | |
31 | -#define MODE_NOCOLOUR 0x4000 /**< No mIRC/ANSI colors/bold */ | |
32 | -#define MODE_NOCTCP 0x8000 /**< No channel CTCPs */ | |
33 | -#define MODE_NONOTICE 0x10000 /**< No channel notices */ | |
34 | +#define MODE_NOCOLOUR 0x4000 /**< +c No mIRC/ANSI colors/bold */ | |
35 | +#define MODE_NOCTCP 0x8000 /**< +C No channel CTCPs */ | |
36 | +#define MODE_NONOTICE 0x10000 /**< +N No channel notices */ | |
37 | #define MODE_SAVE 0x20000 /**< save this mode-with-arg 'til | |
38 | * later */ | |
39 | #define MODE_FREE 0x40000 /**< string needs to be passed to | |
40 | @@ -115,7 +115,7 @@ | |
41 | #define MODE_APASS 0x200000 | |
42 | #define MODE_WASDELJOINS 0x400000 /**< Not DELJOINS, but some joins | |
43 | * pending */ | |
44 | -#define MODE_NOQUITPARTS 0x800000 | |
45 | +#define MODE_NOQUITPARTS 0x800000 /**< +u No user defined quit or part messages */ | |
46 | ||
47 | #define MODE_NOMULTITARGET 0x1000000 /**< +T No multiple targets */ | |
48 | #define MODE_MODERATENOREG 0x2000000 /**< +M Moderate unauthed users */ | |
49 | @@ -396,8 +396,10 @@ | |
50 | ||
51 | extern const char* find_no_nickchange_channel(struct Client* cptr); | |
52 | extern struct Membership* find_channel_member(struct Client* cptr, struct Channel* chptr); | |
53 | -extern int member_can_send_to_channel(struct Membership* member, int reveal); | |
54 | -extern int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal); | |
55 | +extern int member_can_send_to_channel(struct Membership* member, int reveal, | |
56 | + unsigned int flags, const char *text, const int target); | |
57 | +extern int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, | |
58 | + int reveal, unsigned int flags, const char *text, const int target); | |
59 | ||
60 | extern void remove_user_from_channel(struct Client *sptr, struct Channel *chptr); | |
61 | extern void remove_user_from_all_channels(struct Client* cptr); | |
62 | diff -r 7113a0179d71 ircd/channel.c | |
63 | --- a/ircd/channel.c Wed Jan 21 16:44:50 2009 +0100 | |
64 | +++ b/ircd/channel.c Wed Jan 21 17:13:44 2009 +0100 | |
65 | @@ -681,10 +681,14 @@ | |
66 | * @param member The membership of the user | |
67 | * @param reveal If true, the user will be "revealed" on a delayed | |
68 | * joined channel. | |
69 | + * @param flags The bitmask of additional modes to check (besides +n +m +r +M +b) | |
70 | + * @param text The message from the user, needed for modes +c and +C | |
71 | + * @param target The number of targets the message is sent to, for +T | |
72 | * | |
73 | * @returns True if the client can speak on the channel. | |
74 | */ | |
75 | -int member_can_send_to_channel(struct Membership* member, int reveal) | |
76 | +int member_can_send_to_channel(struct Membership* member, int reveal, | |
77 | + unsigned int flags, const char *text, const int target) | |
78 | { | |
79 | assert(0 != member); | |
80 | ||
81 | @@ -692,15 +696,17 @@ | |
82 | * temporary desynch, or maybe they are on an older server, but | |
83 | * we do not want to send ERR_CANNOTSENDTOCHAN more than once. | |
84 | */ | |
85 | - if (!MyUser(member->user)) | |
86 | - { | |
87 | + /* client on service server (+s) - let it through */ | |
88 | + if (IsService(cli_user(member->user)->server)) { | |
89 | if (IsDelayedJoin(member) && reveal) | |
90 | RevealDelayedJoin(member); | |
91 | return 1; | |
92 | } | |
93 | - | |
94 | - /* +X user can always speak on the channel */ | |
95 | + | |
96 | + /* +X exclude +X clients from modes +mMR and bans */ | |
97 | if (IsXtraOp(member->user)) { | |
98 | + if (!can_send_to_channel(member->user, member->channel, flags, text, target)) | |
99 | + return 0; | |
100 | if (IsDelayedJoin(member) && reveal) | |
101 | RevealDelayedJoin(member); | |
102 | return 1; | |
103 | @@ -712,7 +718,7 @@ | |
104 | ||
105 | /* If you have voice or ops, you can speak. */ | |
106 | if (IsVoicedOrOpped(member)) | |
107 | - return 1; | |
108 | + return can_send_to_channel(member->user, member->channel, flags, text, target); | |
109 | ||
110 | /* | |
111 | * If it's moderated, and you aren't a privileged user, you can't | |
112 | @@ -727,6 +733,23 @@ | |
113 | ||
114 | /* If you're banned then you can't speak either. */ | |
115 | if (is_banned(member)) | |
116 | + return 0; | |
117 | + | |
118 | + /* enough checked for remote users */ | |
119 | + if (!MyUser(member->user)) { | |
120 | + if (IsDelayedJoin(member) && reveal) | |
121 | + RevealDelayedJoin(member); | |
122 | + return 1; | |
123 | + } | |
124 | + | |
125 | + /* +u check for user defined quit and part messages, | |
126 | + * and they are not allowed | |
127 | + */ | |
128 | + if ((flags & MODE_NOQUITPARTS) && (member->channel->mode.mode & MODE_NOQUITPARTS)) | |
129 | + return 0; | |
130 | + | |
131 | + /* check various other modes (like cCNT) */ | |
132 | + if (!can_send_to_channel(member->user, member->channel, flags, text, target)) | |
133 | return 0; | |
134 | ||
135 | if (IsDelayedJoin(member) && reveal) | |
136 | @@ -744,16 +767,22 @@ | |
137 | * @param chptr The channel to check | |
138 | * @param reveal If the user should be revealed (see | |
139 | * member_can_send_to_channel()) | |
140 | + * @param flags The bitmask of additional modes to check (besides +n +m +r +M +b) | |
141 | + * @param text The message needed to check for +c and +C | |
142 | + * @param target The number of targets the message is sent to, for +T | |
143 | * | |
144 | * @returns true if the client is allowed to speak on the channel, false | |
145 | * otherwise | |
146 | * | |
147 | * @see member_can_send_to_channel() | |
148 | */ | |
149 | -int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal) | |
150 | +int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal, | |
151 | + unsigned int flags, const char *text, const int target) | |
152 | { | |
153 | struct Membership *member; | |
154 | - assert(0 != cptr); | |
155 | + | |
156 | + assert(0 != cptr); | |
157 | + | |
158 | /* | |
159 | * Servers can always speak on channels. | |
160 | */ | |
161 | @@ -767,15 +796,90 @@ | |
162 | * or +m (moderated). | |
163 | */ | |
164 | if (!member) { | |
165 | - if (IsXtraOp(cptr)) | |
166 | + /* client on service server (+s) - let it through */ | |
167 | + if (IsService(cli_user(cptr)->server)) | |
168 | return 1; | |
169 | - else if ((chptr->mode.mode & (MODE_NOPRIVMSGS|MODE_MODERATED)) || | |
170 | - ((chptr->mode.mode & (MODE_REGONLY|MODE_MODERATENOREG)) && !IsAccount(cptr))) | |
171 | + /* client with umode +X exempt from modes +nmrM and bans */ | |
172 | + if (!IsXtraOp(cptr)) { | |
173 | + if ((chptr->mode.mode & (MODE_NOPRIVMSGS|MODE_MODERATED)) || | |
174 | + ((chptr->mode.mode & (MODE_REGONLY|MODE_MODERATENOREG)) && !IsAccount(cptr))) | |
175 | + return 0; | |
176 | + if (find_ban(cptr, chptr->banlist)) | |
177 | + return 0; | |
178 | + } | |
179 | + /* check various other modes (like cCNT) */ | |
180 | + if (!can_send_to_channel(cptr, chptr, flags, text, target)) | |
181 | return 0; | |
182 | - else | |
183 | - return !find_ban(cptr, chptr->banlist); | |
184 | } | |
185 | - return member_can_send_to_channel(member, reveal); | |
186 | + return member_can_send_to_channel(member, reveal, flags, text, target); | |
187 | +} | |
188 | + | |
189 | +/** Check if a client can send to a channel. | |
190 | + * | |
191 | + * These checks are done for both clients on and off the channel. | |
192 | + * | |
193 | + * @param cptr The client to check | |
194 | + * @param chptr The channel to check | |
195 | + * @param flags The bitmask of modes to check | |
196 | + * @param text The message needed to check for +c and +C | |
197 | + * @param target The number of targets the message is sent to, for +T | |
198 | + * | |
199 | + * @returns true if the client is allowed to speak on the channel, false | |
200 | + * otherwise | |
201 | + * | |
202 | + * @see client_can_send_to_channel() | |
203 | + * @see member_can_send_to_channel() | |
204 | + */ | |
205 | +int can_send_to_channel(struct Client *cptr, struct Channel *chptr, | |
206 | + unsigned int flags, const char *text, const int target) | |
207 | +{ | |
208 | + const char *ch; | |
209 | + unsigned int modes; | |
210 | + int controlcodes = 0; | |
211 | + | |
212 | + assert(0 != cptr); | |
213 | + assert(0 != chptr); | |
214 | + | |
215 | + modes = chptr->mode.mode; | |
216 | + | |
217 | + /* only check these modes on local users */ | |
218 | + if (!MyUser(cptr)) | |
219 | + return 1; | |
220 | + | |
221 | + /* +T check for multi target message and they are not allowed */ | |
222 | + if ((flags & MODE_NOMULTITARGET) && (modes & MODE_NOMULTITARGET) && | |
223 | + target > 1) | |
224 | + return 0; | |
225 | + | |
226 | + /* +N check for channel wide notice and they are not allowed */ | |
227 | + if ((flags & MODE_NONOTICE) && (modes & MODE_NONOTICE)) | |
228 | + return 0; | |
229 | + | |
230 | + /* these last two checks should always be last | |
231 | + * as they loop over the entire message in search for | |
232 | + * CTCP char and control codes | |
233 | + */ | |
234 | + /* +C check for CTCP and CTCPs are not allowed */ | |
235 | + if ((flags & MODE_NOCTCP) && (modes & MODE_NOCTCP) && (text != NULL) && | |
236 | + ircd_strncmp(text,"\001ACTION ",8)) { | |
237 | + for (ch=text;*ch;) { | |
238 | + if (*ch++==1) | |
239 | + return 0; | |
240 | + if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) | |
241 | + controlcodes = 1; | |
242 | + } | |
243 | + } | |
244 | + | |
245 | + /* +c check for control codes and they are not allowed */ | |
246 | + if ((flags & MODE_NOCOLOUR) && (modes & MODE_NOCOLOUR) && (text != NULL)) { | |
247 | + if (controlcodes) /* already found control codes */ | |
248 | + return 0; | |
249 | + for (ch=text;*ch;ch++) { | |
250 | + if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) | |
251 | + return 0; | |
252 | + } | |
253 | + } | |
254 | + return 1; | |
255 | } | |
256 | ||
257 | /** Returns the name of a channel that prevents the user from changing nick. | |
258 | @@ -3625,13 +3729,11 @@ | |
259 | /* Send notification to channel */ | |
260 | if (!(flags & (CHFL_ZOMBIE | CHFL_DELAYED))) | |
261 | sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_PART, chan, NULL, 0, | |
262 | - ((flags & CHFL_BANNED) || ((chan->mode.mode & MODE_NOQUITPARTS) | |
263 | - && !IsChannelService(member->user)) || !jbuf->jb_comment) ? | |
264 | + ((flags & CHFL_BANNED) || !jbuf->jb_comment) ? | |
265 | "%H" : "%H :%s", chan, jbuf->jb_comment); | |
266 | else if (MyUser(jbuf->jb_source)) | |
267 | sendcmdto_one(jbuf->jb_source, CMD_PART, jbuf->jb_source, | |
268 | - ((flags & CHFL_BANNED) || (chan->mode.mode & MODE_NOQUITPARTS) | |
269 | - || !jbuf->jb_comment) ? | |
270 | + ((flags & CHFL_BANNED) || !jbuf->jb_comment) ? | |
271 | ":%H" : "%H :%s", chan, jbuf->jb_comment); | |
272 | /* XXX: Shouldn't we send a PART here anyway? */ | |
273 | /* to users on the channel? Why? From their POV, the user isn't on | |
274 | diff -r 7113a0179d71 ircd/ircd_relay.c | |
275 | --- a/ircd/ircd_relay.c Wed Jan 21 16:44:50 2009 +0100 | |
276 | +++ b/ircd/ircd_relay.c Wed Jan 21 17:13:44 2009 +0100 | |
277 | @@ -87,7 +87,6 @@ | |
278 | void relay_channel_message(struct Client* sptr, const char* name, const char* text, const int targetc) | |
279 | { | |
280 | struct Channel* chptr; | |
281 | - const char *ch; | |
282 | assert(0 != sptr); | |
283 | assert(0 != name); | |
284 | assert(0 != text); | |
285 | @@ -99,35 +98,19 @@ | |
286 | /* | |
287 | * This first: Almost never a server/service | |
288 | */ | |
289 | - if (!client_can_send_to_channel(sptr, chptr, 1)) { | |
290 | + if (!client_can_send_to_channel(sptr, chptr, 1, | |
291 | + (MODE_NOCOLOUR | MODE_NOCTCP | MODE_NOMULTITARGET), text, targetc)) { | |
292 | send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); | |
293 | return; | |
294 | } | |
295 | + /* TODO: what is this again? | |
296 | + * client_can_send_to_channel already reveals delayed join user | |
297 | + * locally anyway, and now the message gets denied? | |
298 | + * hmm... | |
299 | + */ | |
300 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
301 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
302 | return; | |
303 | - | |
304 | - /* +T check */ | |
305 | - if ((chptr->mode.mode & MODE_NOMULTITARGET) && (targetc > 1)) { | |
306 | - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); | |
307 | - return; | |
308 | - } | |
309 | - | |
310 | - /* +cC checks */ | |
311 | - if (chptr->mode.mode & MODE_NOCOLOUR) | |
312 | - for (ch=text;*ch;ch++) | |
313 | - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) { | |
314 | - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); | |
315 | - return; | |
316 | - } | |
317 | - | |
318 | - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(text,"\001ACTION ",8)) | |
319 | - for (ch=text;*ch;) | |
320 | - if (*ch++==1) { | |
321 | - send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); | |
322 | - return; | |
323 | - } | |
324 | - | |
325 | ||
326 | sendcmdto_channel_butone(sptr, CMD_PRIVATE, chptr, cli_from(sptr), | |
327 | SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text); | |
328 | @@ -143,7 +126,6 @@ | |
329 | void relay_channel_notice(struct Client* sptr, const char* name, const char* text, const int targetc) | |
330 | { | |
331 | struct Channel* chptr; | |
332 | - const char *ch; | |
333 | assert(0 != sptr); | |
334 | assert(0 != name); | |
335 | assert(0 != text); | |
336 | @@ -153,30 +135,14 @@ | |
337 | /* | |
338 | * This first: Almost never a server/service | |
339 | */ | |
340 | - if (!client_can_send_to_channel(sptr, chptr, 1)) | |
341 | + if (!client_can_send_to_channel(sptr, chptr, 1, | |
342 | + (MODE_NONOTICE | MODE_NOCOLOUR | MODE_NOCTCP | MODE_NOMULTITARGET), text, targetc)) | |
343 | return; | |
344 | ||
345 | + /* TODO: idem as in previous function */ | |
346 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
347 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
348 | return; | |
349 | - | |
350 | - if ((chptr->mode.mode & MODE_NONOTICE)) | |
351 | - return; | |
352 | - | |
353 | - /* +T check */ | |
354 | - if ((chptr->mode.mode & MODE_NOMULTITARGET) && (targetc > 1)) | |
355 | - return; | |
356 | - | |
357 | - /* +cC checks */ | |
358 | - if (chptr->mode.mode & MODE_NOCOLOUR) | |
359 | - for (ch=text;*ch;ch++) | |
360 | - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) | |
361 | - return; | |
362 | - | |
363 | - if (chptr->mode.mode & MODE_NOCTCP) | |
364 | - for (ch=text;*ch;) | |
365 | - if (*ch++==1) | |
366 | - return; | |
367 | ||
368 | sendcmdto_channel_butone(sptr, CMD_NOTICE, chptr, cli_from(sptr), | |
369 | SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text); | |
370 | @@ -204,7 +170,7 @@ | |
371 | * This first: Almost never a server/service | |
372 | * Servers may have channel services, need to check for it here | |
373 | */ | |
374 | - if (client_can_send_to_channel(sptr, chptr, 1) || IsChannelService(sptr)) { | |
375 | + if (client_can_send_to_channel(sptr, chptr, 1, 0, NULL, 1)) { | |
376 | sendcmdto_channel_butone(sptr, CMD_PRIVATE, chptr, cli_from(sptr), | |
377 | SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text); | |
378 | } | |
379 | @@ -232,7 +198,8 @@ | |
380 | * This first: Almost never a server/service | |
381 | * Servers may have channel services, need to check for it here | |
382 | */ | |
383 | - if (client_can_send_to_channel(sptr, chptr, 1) || IsChannelService(sptr)) { | |
384 | + /* TODO: check how we get here */ | |
385 | + if (client_can_send_to_channel(sptr, chptr, 1, 0, NULL, 1)) { | |
386 | sendcmdto_channel_butone(sptr, CMD_NOTICE, chptr, cli_from(sptr), | |
387 | SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text); | |
388 | } | |
389 | diff -r 7113a0179d71 ircd/m_part.c | |
390 | --- a/ircd/m_part.c Wed Jan 21 16:44:50 2009 +0100 | |
391 | +++ b/ircd/m_part.c Wed Jan 21 17:13:44 2009 +0100 | |
392 | @@ -140,7 +140,8 @@ | |
393 | ||
394 | assert(!IsZombie(member)); /* Local users should never zombie */ | |
395 | ||
396 | - if (!member_can_send_to_channel(member, 0)) | |
397 | + /* check +u here or later somewhere in channel.c ? */ | |
398 | + if (!member_can_send_to_channel(member, 0, MODE_NOQUITPARTS, NULL, 1)) | |
399 | { | |
400 | flags |= CHFL_BANNED; | |
401 | /* Remote clients don't want to see a comment either. */ | |
402 | diff -r 7113a0179d71 ircd/m_quit.c | |
403 | --- a/ircd/m_quit.c Wed Jan 21 16:44:50 2009 +0100 | |
404 | +++ b/ircd/m_quit.c Wed Jan 21 17:13:44 2009 +0100 | |
405 | @@ -109,8 +109,8 @@ | |
406 | struct Membership* chan; | |
407 | /* (slug for +u) removed !IsDelayedJoin(chan) as splidge said to */ | |
408 | for (chan = cli_user(sptr)->channel; chan; chan = chan->next_channel) { | |
409 | - if (!IsZombie(chan) && (!member_can_send_to_channel(chan, 0) | |
410 | - || (chan->channel->mode.mode & MODE_NOQUITPARTS))) | |
411 | + if (!IsZombie(chan) && (!member_can_send_to_channel(chan, 0, | |
412 | + MODE_NOQUITPARTS, NULL, 1))) | |
413 | return exit_client(cptr, sptr, sptr, "Signed off"); | |
414 | } | |
415 | } | |
416 | diff -r 7113a0179d71 ircd/m_topic.c | |
417 | --- a/ircd/m_topic.c Wed Jan 21 16:44:50 2009 +0100 | |
418 | +++ b/ircd/m_topic.c Wed Jan 21 17:13:44 2009 +0100 | |
419 | @@ -144,7 +144,7 @@ | |
420 | } | |
421 | else if ((chptr->mode.mode & MODE_TOPICLIMIT) && !is_chan_op(sptr, chptr)) | |
422 | send_reply(sptr, ERR_CHANOPRIVSNEEDED, chptr->chname); | |
423 | - else if (!client_can_send_to_channel(sptr, chptr, 1)) | |
424 | + else if (!client_can_send_to_channel(sptr, chptr, 1, 0, NULL, 1)) | |
425 | send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname); | |
426 | else | |
427 | do_settopic(sptr,cptr,chptr,topic,0); | |
428 | diff -r 7113a0179d71 ircd/m_wallchops.c | |
429 | --- a/ircd/m_wallchops.c Wed Jan 21 16:44:50 2009 +0100 | |
430 | +++ b/ircd/m_wallchops.c Wed Jan 21 17:13:44 2009 +0100 | |
431 | @@ -103,7 +103,6 @@ | |
432 | { | |
433 | struct Channel *chptr; | |
434 | struct Membership* member; | |
435 | - const char *ch; | |
436 | ||
437 | assert(0 != cptr); | |
438 | assert(cptr == sptr); | |
439 | @@ -117,23 +116,12 @@ | |
440 | return send_reply(sptr, ERR_NOTEXTTOSEND); | |
441 | ||
442 | if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) { | |
443 | - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) { | |
444 | + /* check also for modes +N +c and +C */ | |
445 | + if (client_can_send_to_channel(sptr, chptr, 0, | |
446 | + (MODE_NONOTICE | MODE_NOCOLOUR | MODE_NOCTCP), parv[parc - 1], 1)) { | |
447 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
448 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
449 | return 0; | |
450 | - | |
451 | - /* +cC checks */ | |
452 | - if (chptr->mode.mode & MODE_NOCOLOUR) | |
453 | - for (ch=parv[parc - 1];*ch;ch++) | |
454 | - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) { | |
455 | - return 0; | |
456 | - } | |
457 | - | |
458 | - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8)) | |
459 | - for (ch=parv[parc - 1];*ch;) | |
460 | - if (*ch++==1) { | |
461 | - return 0; | |
462 | - } | |
463 | ||
464 | /* Reveal delayedjoin user */ | |
465 | if ((member = find_member_link(chptr, cptr)) && IsDelayedJoin(member)) | |
466 | @@ -165,7 +153,7 @@ | |
467 | return 0; | |
468 | ||
469 | if (!IsLocalChannel(parv[1]) && (chptr = FindChannel(parv[1]))) { | |
470 | - if (client_can_send_to_channel(sptr, chptr, 1)) { | |
471 | + if (client_can_send_to_channel(sptr, chptr, 1, 0, NULL, 1)) { | |
472 | sendcmdto_channel_butone(sptr, CMD_WALLCHOPS, chptr, cptr, | |
473 | SKIP_DEAF | SKIP_BURST | SKIP_NONOPS, | |
474 | "%H :%s", chptr, parv[parc - 1]); | |
475 | diff -r 7113a0179d71 ircd/m_wallvoices.c | |
476 | --- a/ircd/m_wallvoices.c Wed Jan 21 16:44:50 2009 +0100 | |
477 | +++ b/ircd/m_wallvoices.c Wed Jan 21 17:13:44 2009 +0100 | |
478 | @@ -102,7 +102,6 @@ | |
479 | { | |
480 | struct Channel *chptr; | |
481 | struct Membership* member; | |
482 | - const char *ch; | |
483 | ||
484 | assert(0 != cptr); | |
485 | assert(cptr == sptr); | |
486 | @@ -116,23 +115,11 @@ | |
487 | return send_reply(sptr, ERR_NOTEXTTOSEND); | |
488 | ||
489 | if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) { | |
490 | - if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) { | |
491 | + if (client_can_send_to_channel(sptr, chptr, 0, | |
492 | + (MODE_NONOTICE | MODE_NOCOLOUR | MODE_NOCTCP), parv[parc - 1], 1)) { | |
493 | if ((chptr->mode.mode & MODE_NOPRIVMSGS) && | |
494 | check_target_limit(sptr, chptr, chptr->chname, 0)) | |
495 | return 0; | |
496 | - | |
497 | - /* +cC checks */ | |
498 | - if (chptr->mode.mode & MODE_NOCOLOUR) | |
499 | - for (ch=parv[parc - 1];*ch;ch++) | |
500 | - if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) { | |
501 | - return 0; | |
502 | - } | |
503 | - | |
504 | - if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8)) | |
505 | - for (ch=parv[parc - 1];*ch;) | |
506 | - if (*ch++==1) { | |
507 | - return 0; | |
508 | - } | |
509 | ||
510 | /* Reveal delayedjoin user */ | |
511 | if ((member = find_member_link(chptr, cptr)) && IsDelayedJoin(member)) | |
512 | @@ -164,7 +151,7 @@ | |
513 | return 0; | |
514 | ||
515 | if (!IsLocalChannel(parv[1]) && (chptr = FindChannel(parv[1]))) { | |
516 | - if (client_can_send_to_channel(sptr, chptr, 1)) { | |
517 | + if (client_can_send_to_channel(sptr, chptr, 1, 0, NULL, 1)) { | |
518 | sendcmdto_channel_butone(sptr, CMD_WALLVOICES, chptr, cptr, | |
519 | SKIP_DEAF | SKIP_BURST | SKIP_NONVOICES, | |
520 | "%H :%s", chptr, parv[parc - 1]); |