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